这是一个树形DP
关于树形DP:我都快忘了
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long m,n,k,x,y,f[100010];
long long cd;
string s[100000];
long long dp(int x,int y,int z)
{
if(z>m)
return f[y-x+1];
char c=s[x][z];
int j=x,t=1;
long long ans=1;
for(int i=x+1; i<=y; i++)
{
if(c!=s[i][z])
{
t++;
ans=(ans*dp(j,i-1,z+1))%1000000007;
j=i;
c=s[i][z];
}
}
if(j!=y)
ans=(ans*dp(j,y,z+1))%1000000007;
ans=(ans*f[t])%1000000007;
return ans;
}
void sort1(int l,int r)
{
if(l>r)
return;
int i=l,j=r;
string m=s[r];
string z;
while(i<=j)
{
while(s[i]>m) i++;
while(s[j]<m) j--;
if(i<=j)
{
z=s[i];
s[i]=s[j];
s[j]=z;
i++;
j--;
}
}
sort1(l,j);
sort1(i,r);
}
int main()
{
freopen("ranking.in","r",stdin);
freopen("ranking.out","w",stdout);
f[0]=1;
for(int i=1; i<=3000; i++)
f[i]=(f[i-1]*i)%1000000007;
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>s[i];
long long cd=s[i].size();
m=max(m,cd);
}
for(int i=1; i<=n; i++)
for(int j=s[i].size()+1; j<=m; j++)
s[i]=s[i]+' ';
sort1(1,n);
cout<<dp(1,n,0);
return 0;
}