题意:给定一个数字<=10^100000,一次将该数的第一位放到放到最后一位,求所有组成的不同的数比原数小的个数,
相等的个数,大的个数
分析:由于输入的数太大了,只能当作字符串处理,将输入的原串粘贴在后面,
这样就可以对原串进行EKMP,最终只要统计从第i个位置开始的extend[i],
如果>=len则从第i个位置开始的组成的数与原数相等,否则只要比较s[i]与s[i+next[i]]即可
// Created by Chenhongwei in 2015.
// Copyright (c) 2015 Chenhongwei. All rights reserved.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
const int inf=1e9;
const int maxn=1e6+100;
typedef long long ll;
typedef unsigned long long ull;
char s[maxn];
int nxt[maxn];
void pre_exkmp(char *t,int len)
{
nxt[0]=len;
int j=0;
while(j+1<len&&t[j+1]==t[j]) j++;
nxt[1]=j;
int a=1,p,l;
for(int i=2;i<len;i++)
{
p=a+nxt[a]-1;
l=nxt[i-a];
if(i+l<p+1)
nxt[i]=l;
else
{
j=max(0,p-i+1);
while(i+j<len&&t[i+j]==t[j])
j++;
nxt[i]=j;
a=i;
}
}
}
int main()
{
//ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T,kase=0;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
int len=strlen(s);
for(int i=0;i<len;i++)
s[i+len]=s[i];
s[len*2]='\0';
pre_exkmp(s,len*2);
int k,l=0,e=0,g=0;
for(int i=1;i<=len;i++)
{
if(i+nxt[i]>=len)
{
k=len%i?len:i;
break;
}
}
for(int i=0;i<k;i++)
{
if(nxt[i]>=len)
e++;
else
{
if(s[i+nxt[i]]>s[nxt[i]])
g++;
else
l++;
}
}
printf("Case %d: %d %d %d\n",++kase,l,e,g);
}
return 0;
}