hdu4333 扩展KMP

一次将第一个数放到最后一个,求所有不同的数中比原串小的个数,等于个数,大于个数

思路:将原串贴在后面,求一遍与原串的EXKMP,然后利用extend

if extend[i]>=len 等于原串

else if s[i+extend[i]]>s[i] 大于原串

else 小于原串

然后利用KMPdenext数组求出循环节所有值除以循环节即可

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 char S[200005],T[200005];
 6 int next[200005],extend[200005];
 7 void EKMP(char s[],char t[])
 8 {
 9   int i,j,lens,lent,a,p,l;
10   lens=strlen(s);
11   lent=strlen(t);
12   
13   next[0]=lent;
14   j=0;
15   while (j+1<lent&&t[j]==t[j+1]) j++;
16   next[1]=j;
17   a=1;
18   for (i=2;i<lent;i++)
19   {
20     p=next[a]+a-1;
21     l=next[i-a];
22     if (i+l<p+1) next[i]=l;
23     else{
24       j=max(0,p-i+1);
25       while (i+j<lent&&t[i+j]==t[j]) j++;
26       next[i]=j;
27       a=i;
28     }
29   }
30 
31   j=0;
32   while (j<lens&&j<lent&&s[j]==t[j]) j++;
33   extend[0]=j;
34   a=0;
35   for (i=1;i<lens;i++)
36   {
37     p=extend[a]+a-1;
38     l=next[i-a];
39     if (l+i<p+1) extend[i]=l;
40     else{
41       j=max(0,p-i+1);
42       while (i+j<lens&&j<lent&&s[i+j]==t[j]) j++;
43       extend[i]=j;
44       a=i;
45     }
46   }
47 
48 }
49 void getnext(char s[],int n)
50 {
51   int i,j;
52   next[1]=j=0;
53   for (i=2;i<=n;i++)
54   {
55     while (j>0&&s[j+1]!=s[i]) j=next[j];
56     if (s[j+1]==s[i]) j++;
57     next[i]=j;
58   }
59 }
60 int main()
61 {
62   int Case,t,len,t1,t2,t3,cnt,i;
63   scanf("%d",&Case);
64   for (t=1;t<=Case;t++)
65   {
66     scanf("%s",S);
67     len=strlen(S);
68     strcpy(T,S); strcat(T,S);
69     EKMP(T,S);
70     t1=t2=t3=0;
71     for (i=0;i<len;i++)
72       if (extend[i]>=len) t2++;
73       else if (T[i+extend[i]]<S[extend[i]]) t1++;
74       else t3++;
75     for (i=len;i>=1;i--) T[i]=S[i-1];
76     getnext(T,len);
77     if (len%(len-next[len])!=0) cnt=1;
78     else cnt=len/(len-next[len]);
79     printf("Case %d: %d %d %d\n",t,t1/cnt,t2/cnt,t3/cnt);
80   }
81   return 0;
82 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333

posted on 2015-02-02 23:52  xiao_xin  阅读(90)  评论(0编辑  收藏  举报

导航