rt,按照题解第二篇的思路写的,有些地方不同,WA#12,求 dalao 救救QAQ
#include<vector>
#include<iostream>
#define C 1145141
#define int long long
#define mod 1000000007
#define ull unsigned long long
using namespace std;
const int N=1e6+5;
int n,now,las,ans,len[2],dp[2][N],id[2][N];
ull pow[N],has[2][N];
string s[2];
void init(){
pow[0]=1;
for(int i=1;i<=1000000;i++) pow[i]=pow[i-1]*C;
}
ull Find(int pl,int pos,int x){
if(pos>x) return has[pl][x];
x+=1;//会因为pos导致顺延
return (has[pl][x]-has[pl][pos]*pow[x-pos])+has[pl][pos-1]*pow[x-(pos+1)+1];
}
bool ok(int pos1,int pos2){
int a=len[now],b=len[las];
int l=1,r=min(a,b)-1,an=C,mid;
while(l<=r){
mid=(l+r)/2;
if(Find(now,pos1,mid)==Find(las,pos2,mid)) l=mid+1;
else r=mid-1,an=mid;
}
if(an==C) return 1;
return ((an<pos1||an>=a)?s[now][an]:s[now][an+1])>=
((an<pos2||an>=b)?s[las][an]:s[las][an+1]);
}
void work(int op){
int l=1,r=len[now],p=1;
for(int i=1;i<s[op].size();i++)
has[op][i]=has[op][i-1]*C+(s[op][i]-'a'+1);
for(int i=1;i<=len[now];i++){
if(s[op][i]>s[op][i+1]){
for(int j=p;j<=i;j++) id[op][l++]=j;
p=i+1;
}
else if(s[op][i]<s[op][i+1]){
for(int j=i;j>=p;j--) id[op][r--]=j;
p=i+1;
}
}
for(int j=p;j<=len[now];j++) id[op][l++]=j;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;init();
for(int i=1;i<=n;i++){
las=now;now=las^1;
cin>>s[now];s[now]='6'+s[now]+'.';len[now]=s[now].size()-1;work(now);
if(i==1){
for(int i=1;i<=len[now];i++) dp[now][i]=1;
continue;
}
for(int j=1,k=1;j<=len[now];j++){
dp[now][j]=dp[now][j-1];
while(k<=len[las]&&ok(id[now][j],id[las][k])){
dp[now][j]=(dp[now][j]+dp[las][k++])%mod;
}
}
}
for(int i=1;i<=len[now];i++) ans=(ans+dp[now][i])%mod;
cout<<ans;
return 0;
}