比赛记录
lfw高精度水题签一年到,还忘记清空原数组WA了一发,3个人基础的数学知识不知道,就是3次方以上的多项式全部都可以分解。
字符串最小表示法lfw的模板里没有,从高中考试的zyj代码里贴了过来。。。而且n^3可以过,不会写nlogn。。。
E题lfw太久没写离散化后点表示区间的线段树题了,导致到结束也没写完E题,而且对于到线段树中二分找临界值不熟练,赛后补题WA了。
题目链接:https://ac.nowcoder.com/acm/contest/887#question
题解
A String
111,000,连续的一定在一段中,枚举开头,然后看最远能到哪个位置,这段字符串最小表示是本身,然后这一段就作为划分的一段
1 #include<bits/stdc++.h> 2 #define maxl 210000 3 using namespace std; 4 5 int n; 6 int a[maxl],b[maxl],sum[maxl]; 7 char s[maxl],ch[maxl]; 8 bool cut[maxl]; 9 10 inline void prework() 11 { 12 scanf("%s",s+1); 13 n=strlen(s+1); 14 for(int i=1;i<=n;i++) 15 cut[i]=false; 16 a[0]=0; 17 int cnt=1; 18 for(int i=2;i<=n;i++) 19 if(s[i]==s[i-1]) 20 cnt++; 21 else 22 { 23 a[++a[0]]=cnt;b[a[0]]=s[i-1]-'0'; 24 cnt=1; 25 } 26 a[++a[0]]=cnt;b[a[0]]=s[n]-'0'; 27 for(int i=1;i<=a[0];i++) 28 sum[i]=sum[i-1]+a[i]; 29 } 30 31 inline int MP(char* ch,int n) 32 { 33 int i=0,j=1,k=0; 34 while(i<n && j<n && k<n){ 35 int t=ch[(i+k)%n]-ch[(j+k)%n]; 36 if(t==0) k++; 37 else{ 38 if(t>0) i+=(k+1); 39 else j+=(k+1); 40 if(i==j) j++; 41 k=0; 42 } 43 } 44 return min(i,j); 45 } 46 47 inline bool jug(int st,int ed) 48 { 49 int n=0; 50 for(int i=st;i<=ed;i++) 51 for(int j=1;j<=a[i];j++) 52 ch[n++]=b[i]+'0'; 53 if(MP(ch,n)==0) 54 return true; 55 else 56 return false; 57 } 58 59 inline void mainwork() 60 { 61 int st,flag,i,ed; 62 st=1; 63 while(st<=a[0]) 64 { 65 ed=st; 66 for(int i=a[0];i>=st+1;i--) 67 if(jug(st,i)) 68 { 69 ed=i; 70 break; 71 } 72 cut[sum[ed]]=true; 73 st=ed+1; 74 } 75 } 76 77 inline void print() 78 { 79 for(int i=1;i<=a[0];i++) 80 { 81 for(int j=1;j<=a[i];j++) 82 putchar(b[i]+'0'); 83 if(i==a[0]) 84 puts(""); 85 else 86 if(cut[sum[i]]) 87 putchar(' '); 88 } 89 } 90 91 int main() 92 { 93 int t; 94 scanf("%d",&t); 95 for(int i=1;i<=t;i++) 96 { 97 prework(); 98 mainwork(); 99 print(); 100 } 101 return 0; 102 }