hdu4333

题解:

EX_KMP

先把串复制一遍放到后面

这样旋转就是每一个前缀了

然后做一个EX_KMP

然后看一下后一个字符谁大谁小

代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define next ____next
const int N=200005;
char s[N];
int T,next[N],cas;
void getnext(char *a,int len)
{
    int i=-1,j=0;
    next[0]=-1;
    while (j<len)
     {
         if (i==-1||a[i]==a[j])next[++j]=++i;
         else i=next[i];
     }
}
void getex(char *a,int len)
{
    int k=0,i=1;
    next[0]=len;
    while (k+1<len&&a[k]==a[k+1])k++;
    next[1]=k;
    k=1;
    while (++i<=len/2)
     {
         int maxr=next[k]+k-1;
         next[i]=min(next[i-k],max(0,maxr-i+1));
         while (i+next[i]<len&&a[next[i]]==a[next[i]+i])next[i]++;
         if (i+next[i]>k+next[k])k=i;
     }
}
int main()
{
    scanf("%d",&T);
    while (T--)
     {
         scanf("%s",&s);
         int len=strlen(s);
        getnext(s,len);
        int tmp=len%(len-next[len])==0?len/(len-next[len]):1;
        for (int i=0;i<=len;i++)s[i+len]=s[i];
        getex(s,len*2);
        int a=0,b=0,c=0;
        for (int i=0;i<len;i++)
         {
             if (next[i]>=len)b++;
             else if (s[next[i]+i]>s[next[i]])c++;
             else a++;
         } 
        printf("Case %d: %d %d %d
",++cas,a/tmp,b/tmp,c/tmp); 
     }
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8467415.html