http://acm.hdu.edu.cn/showproblem.php?pid=3374
最小表示+KMP
View Code
1 #include <stdio.h>
2 #include <string.h>
3 #define max(a,b) ((a)>(b)?(a):(b))
4 #define min(a,b) ((a)<(b)?(a):(b))
5
6 const int N=1000100;
7 char str[N],dstr[N*2],t[N*2];
8 int fail[N];
9 int minmaxs(const char *str,int cmp)
10 {
11 strcpy(dstr,str);
12 strcat(dstr,str);
13 int i=0,j=1,k=0;
14 int len=strlen(str);
15 while (i<len && j<len)
16 {
17 k=0;
18 while (str[k] && dstr[i+k]==dstr[j+k]) k++;
19 if (!str[k]) break;
20 if (cmp?dstr[i+k]>dstr[j+k]:dstr[i+k]<dstr[j+k])
21 j=max(i+1,j+k+1);
22 else i=max(j+1,i+k+1);
23 }
24 return min(i,j);
25 }
26 void kmp(char *str)
27 {
28 fail[0]=-1;
29 int i,j;
30 for (i=1,j=-1;str[i];i++)
31 {
32 while (j!=-1 && str[i]!=str[j+1]) j=fail[j];
33 if (str[i]==str[j+1]) j++;
34 fail[i]=j;
35 }
36 }
37 int match(char *sa,char *sb)
38 {
39 int i,j,cnt=0;
40 for (i=0,j=0;sa[i];i++)
41 {
42 while (j && sa[i]!=sb[j]) j=fail[j-1]+1;
43 if (sa[i]==sb[j]) j++;
44 if (!sb[j]) {cnt++; j=fail[j-1]+1;}
45 }
46 return cnt;
47 }
48 int main()
49 {
50 int p0,s0,p1,s1,l;
51 while (~scanf("%s",str))
52 {
53 l=strlen(str);
54 p0=minmaxs(str,0);
55 strcpy(t,str); t[l]=0;
56 kmp(t);
57 s0=match(dstr+1,t);
58 p1=minmaxs(str,1);
59 strcpy(t,str); t[l]=0;
60 kmp(t);
61 s1=match(dstr+1,t);
62 printf("%d %d %d %d\n",p0+1,s0,p1+1,s1);
63 }
64 return 0;
65 }