HDU.6761.Minimum Index(Lyndon分解)
思路: 分解。
分三种情况。
令 表示前缀 的最小后缀位置
当 时,说明因为 含有循环节 。所以 。
当 时,说明 本身是一个 串, 。
当 ,需要分解不用处理,但是当 时, 在分解后变为 。
下一次 不会被处理,因为 ,直接处理 了 。所以将 置为 。
时间复杂度:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
char s[N];
int d[N];
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%s",s+1);int n=strlen(s+1),i=1;d[1]=1;
ll ans=0;
while(i<=n){
int j=i,k=i+1;
while(k<=n&&s[j]<=s[k]){
if(s[j]<s[k]) d[k]=i,j=i;
else d[k]=d[j]+(k-j),j++;
k++;
}
d[k]=k;
while(i<=j){
i+=k-j;
}
}
for(int i=n;i>=1;i--) ans=ans*1112+d[i],ans%=mod;
printf("%lld\n",ans);
}
return 0;
}