【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=4333
【题目大意】
给出一个数字,每次将其最后一位提到最前面来,问产生的所有数字中,
有多少比原数大,有多少比原数小,有多少和原数相等
【题解】
我们发现比较字符串形式的两个数的大小,只要比较他们LCP后的第一位即可
我们用exkmp处理LCP的方式处理两倍长原串,然后顺次枚举记录答案即可。
【代码】
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=500010;
int len,LCP[N],ex1[N],ex2[N],a[N],s[N];
char S[N],T[N];
void getLCP(char *T){
int i,len=strlen(T);
LCP[0]=len;
for(i=0;i<len-1&&T[i]==T[i+1];i++);
LCP[1]=i; int a=1;
for(int k=2;k<len;k++){
int p=a+LCP[a]-1,L=LCP[k-a];
if((k-1)+L>=p){
int j=(p-k+1)>0?(p-k+1):0;
while(k+j<len&&T[k+j]==T[j])j++;
LCP[k]=j,a=k;
}else LCP[k]=L;
}
}
int main(){
int Cas;
scanf("%d",&Cas);
for(int cas=1;cas<=Cas;cas++){
int L=0,E=0,G=0;
scanf("%s",S);
int len=strlen(S);
for(int i=0;i<len;i++)S[len+i]=S[i];
S[len*2]='\0';
getLCP(S);
for(int i=0;i<len;i++){
//printf("%d %c %c\n",LCP[i],S[LCP[i]],S[LCP[i]+i]);
if(LCP[i]>=len)E++;
else if(S[LCP[i]]<S[LCP[i]+i])G++;
else L++;
}printf("Case %d: %d %d %d\n",cas,L/E,E/E,G/E);
}return 0;
}