#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 200005;
char str[maxn];
char tmp[maxn/2];
int next[maxn];
int ex[maxn];
int ep[maxn];
void get_next(char *s,int len)
{
next[0]=0;
for(int i=1;i<len;++i)
{
int j=next[i-1];
while(j&&s[j]!=s[i]) j=next[j-1];
if(s[j]==s[i]) j++;
next[i]=j;
}
}
void get_exnext(char *s,int len)
{
int j=0;
ex[0]=len;
while(j+1<len&&s[j]==s[j+1]) j++;
ex[1]=j;
int k=1,p,L;
for(int i=2;i<len;++i)
{
p=k+ex[k]-1;
L=ex[i-k];
if(i+L-1<p) ex[i]=L;
else
{
j=max(0,p-i+1);
while(i+j<len&&s[i+j]==s[j]) j++;
ex[i]=j;
k=i;
}
}
}
void ex_kmp(char *s,int lens,char *t,int lent)
{
int j=0;
while(j<lens && j<lent && s[j]==t[j]) j++;
ep[0]=j;
int k=0,p,L;
for(int i=1;i<lens;++i)
{
p=k+ep[k]-1;
L=ex[i-k];
if(i+L-1<p) ep[i]=L;
else
{
j=max(0,p-i+1);
while(i+j<lens && j<lent && s[i+j]==t[j]) j++;
ep[i]=j;
k=i;
}
}
}
int main()
{
int t;
int lens,lent;
int res1,res2,res3,tot;
bool flag;
scanf("%d",&t);
for(int e=1;e<=t;++e)
{
scanf("%s",tmp);
res1=0;
res2=0;
res3=0;
flag=true;
strcpy(str,tmp);
strcat(str,tmp);
lens=strlen(str);
lent=strlen(tmp);
get_next(tmp,lent);
get_exnext(tmp,lent);
ex_kmp(str,lens,tmp,lent);
for(int i=0;i<lent;++i)
{
if(ep[i]==lent) res2++;
else
{
if(str[i+ep[i]]<tmp[ep[i]]) res1++;
else res3++;
}
}
//kmp计算循环节
if(lent%(lent-next[lent-1])==0) tot=lent/(lent-next[lent-1]);
printf("Case %d: %d %d %d\n",e,res1/tot,res2/tot,res3/tot);
}
return 0;
}
HDU 4333 Revolving Digits (扩展KMP)
最新推荐文章于 2019-05-04 10:54:24 发布