题解:P16780 ⌈Xzy OI R1 T2⌋ 成成边
翻了一下题解区发现都是 Trie 树做法。模拟赛考了这题饭堂了没写 Trie 树。注意到原问题等价于所有二元组
考虑如何求所有二元组
接下来计算位于
lcp 3 1 2 5 4
下标 2 3 4 5 i
这意味着,
LCP(1,i)=1
LCP(2,i)=1
LCP(3,i)=2
LCP(4,i)=4
LCP(5,i)=4
容易发现,由于我们对所有字符串排过序,
因为对固定位置
我们在更新
代码如下,可供参考:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,P=1e9+7;
int n,lcp[N],mi[N],sum,ans,fac=1;
struct Node{
string s;
}a[N];
bool cmp(Node x,Node y){
return x.s<y.s;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i].s;
for(int i=1;i<=n-3;i++)fac=1ll*fac*n%P;
fac=2ll*fac%P;
sort(a+1,a+n+1,cmp);
for(int i=2;i<=n;i++){
int pos=0,len1=a[i-1].s.size(),len2=a[i].s.size();
while(pos<len1&&pos<len2&&a[i-1].s[pos]==a[i].s[pos])pos++;
lcp[i]=pos;sum=(sum+lcp[i])%P;mi[i]=lcp[i];
for(int j=i-1;j>1;j--){
if(mi[j]<=lcp[i])break;
else{
sum=(sum+P-mi[j])%P;
mi[j]=lcp[i];
sum=(sum+mi[j])%P;
}
}
ans=(ans+sum)%P;
}
cout<<1ll*ans*fac%P;
return 0;
}