//Duval#include<bits/stdc++.h>usingnamespace std;constint maxn =5e6+10;char s[maxn];int ans =0;intlyndon(){int n =strlen(s);int i =0, j, k;//读入字符串的开始下标是0while(i < n){
j = i, k = i+1;while(k<n && s[j]<=s[k]){if(s[j]==s[k]) j++, k++;else j = i, k++;}while(i <= j){
i += k-j;//每个lyndon分解的右端点,此时的开始下标按1计算//cout << i << endl;
ans ^= i;}}return ans;}intmain(){scanf("%s", s);printf("%d\n",lyndon());return0;}
s[i…n]的最小后缀的下标 HDU6761
p
o
s
[
i
]
=
i
pos[i]=i
pos[i]=i
s
[
j
]
=
s
[
k
]
:
p
o
s
[
k
]
=
p
o
s
[
j
]
+
k
−
j
s[j]=s[k]: pos[k]=pos[j]+k-j
s[j]=s[k]:pos[k]=pos[j]+k−j
s
[
j
]
<
s
[
k
]
:
p
o
s
[
k
]
=
i
s[j]<s[k]: pos[k]=i
s[j]<s[k]:pos[k]=i
#include<bits/stdc++.h>usingnamespace std;typedeflonglong ll;constint maxn =1e6+10;const ll mod =1e9+7;char s[maxn];
ll ans;int n;
ll pos[maxn];voidlyndon(){int i =0, j, k;//读入字符串的开始下标是0while(i < n){
j = i, k = i+1;
pos[i]= i;while(k<n && s[j]<=s[k]){if(s[j]==s[k]){
pos[k]= pos[j]+k-j;//k-j相当于循环节
j++;}else//回退到i{
pos[k]= i;
j = i;}
k++;}while(i <= j) i += k-j;}}intmain(){int t;scanf("%d",&t);
ll p =0;while(t--){
ans = p =0;scanf("%s", s);
n =strlen(s);lyndon();for(int i =0; i < n; i++){
p = p==0?1:p*1112ll%mod;
ans =(ans%mod +(pos[i]+1)*p%mod)%mod;}printf("%lld\n", ans%mod);}return0;}