标签:ide logs typedef display lin ++i splay href next
http://acm.hdu.edu.cn/showproblem.php?pid=4333
【题意】
【思路】
【AC】
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<cstdio> 5 #include<algorithm> 6 using namespace std; 7 typedef long long ll; 8 const int maxn=2e5+3; 9 char s[maxn]; 10 char t[maxn]; 11 int nxt[maxn]; 12 int extend[maxn]; 13 int nxtval[maxn]; 14 15 16 void pre_EKMP(char x[],int m,int nxt[]) 17 { 18 nxt[0]=m; 19 int j=0; 20 while(j+1<m && x[j]==x[j+1]) j++; 21 nxt[1]=j; 22 int k=1; 23 for(int i=2;i<m;i++) 24 { 25 int p=nxt[k]+k-1; 26 int L=nxt[i-k]; 27 if(i+L<p+1) nxt[i]=L; 28 else 29 { 30 j=max(0,p-i+1); 31 while(i+j<m && x[i+j]==x[j]) j++; 32 nxt[i]=j; 33 k=i; 34 } 35 } 36 } 37 38 void EKMP(char x[],int m,char y[],int n,int nxt[],int extend[]) 39 { 40 pre_EKMP(x,m,nxt);//子串 41 int j=0; 42 while(j<n && j<m &&x[j]==y[j]) j++; 43 extend[0]=j; 44 int k=0; 45 for(int i=1;i<n;i++) 46 { 47 int p=extend[k]+k-1; 48 int L=nxt[i-k]; 49 if(i+L<p+1) extend[i]=L; 50 else 51 { 52 j=max(0,p-i+1); 53 while(i+j<n && j<m && y[i+j]==x[j]) j++; 54 extend[i]=j; 55 k=i; 56 } 57 } 58 } 59 60 void kmp_pre(char x[],int m,int nxtval[]) 61 { 62 int i,j; 63 j=nxtval[0]=-1; 64 i=0; 65 while(i<m) 66 { 67 if(j==-1||x[i]==x[j]) 68 { 69 i++; 70 j++; 71 if(x[i]!=x[j]) nxtval[i]=j; 72 else nxtval[i]=nxtval[j]; 73 } 74 else j=nxtval[j]; 75 } 76 77 } 78 79 void NextVal(char *T) 80 { 81 int i=0,j=-1; 82 nxtval[0]=-1; 83 int Tlen=strlen(T); 84 while(i<Tlen) 85 { 86 if(j==-1||T[i]==T[j]) 87 { 88 i++; 89 j++; 90 if(T[i]!=T[j]) nxtval[i]=j; 91 else nxtval[i]=nxtval[j]; 92 } 93 else j=nxtval[j]; 94 } 95 } 96 97 98 int main() 99 { 100 int T; 101 scanf("%d",&T); 102 int cas=0; 103 while(T--) 104 { 105 scanf("%s",s); 106 strcpy(t,s); 107 strcat(s,t); 108 int a,b,c; 109 a=b=c=0; 110 int ls=strlen(s); 111 int lt=strlen(t); 112 EKMP(t,lt,s,ls,nxt,extend); 113 kmp_pre(t,lt,nxtval); 114 int p=lt-nxtval[lt]; 115 int tmp=1; 116 if(lt%p==0) tmp=lt/p; 117 for(int i=0;i<lt;i++) 118 { 119 if(extend[i]==lt) a++; 120 else if(s[i+extend[i]]>t[extend[i]]) c++; 121 else b++; 122 } 123 printf("Case %d: %d %d %d\n",++cas,b/tmp,a/tmp,c/tmp); 124 } 125 return 0; 126 }
【知识点】
扩展kmp的next数组与kmp数组的next含义不同,是字符串s的所有后缀和s本身的最长公共前缀
【坑点】
做这道题踩了各种坑
void kmp_pre(char x[],int m,int nxtval[]) { int i,j; j=nxtval[0]=-1; i=0; while(i<m) { while(-1!=j && x[i]!=x[j]) j=nxtval[j]; nxtval[++i]=nxtval[++j]; } }
会WA
void kmp_pre(char x[],int m,int nxtval[]) { int i,j; j=nxtval[0]=-1; i=0; while(i<m) { if(j==-1||x[i]==x[j]) { i++; j++; if(x[i]!=x[j]) nxtval[i]=j; else nxtval[i]=nxtval[j]; } else j=nxtval[j]; } }
【扩展kmp+最小循环节】HDU 4333 Revolving Digits
标签:ide logs typedef display lin ++i splay href next
原文地址:http://www.cnblogs.com/itcsl/p/7399750.html