题目大意:
就是求一个串的最大最小表示法的开始下标,然后求有多少个做大最小表示,输出格式为 最小表示下标 它的个数 最大表示下标 它的个数
基本思路:
最小最大表示法模板题,然后求一下循环节,很容易知道,循环节和最大最小表示数量上相等,然后问题就解决啦;
代码如下:
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 1000000+10; char T[maxn]; int len; int nx[maxn]; void getNext(){ int j=0,k=-1; nx[0]=-1; while(j<len){ if(k==-1||T[k]==T[j]){ nx[++j]=++k; }else{ k=nx[k]; } } } int getMin(){ int i=0,j=1,k=0; while(i<len&&j<len&&k<len){ int t=T[(i+k)%len]-T[(j+k)%len]; if(t==0) k++; else{ if(t>0) i+=k+1; else j+=k+1; if(i==j) j++; k=0; } } return min(i,j); } int getMax(){ int i=0,j=1,k=0; while(i<len&&j<len&&k<len){ int t=T[(i+k)%len]-T[(j+k)%len]; if(t==0) k++; else{ if(t>0) j+=k+1; else i+=k+1; if(i==j) j++; k=0; } } return min(i,j); } int main(){ while(scanf("%s",T)!=EOF){ len=strlen(T); getNext(); int mi=getMin(); int mx=getMax(); int t=len-nx[len]; int cnt=1; if(len%t==0) cnt=len/t; printf("%d %d %d %d ",mi+1,cnt,mx+1,cnt); } return 0; }