描述
小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一段音乐旋律可以被表示为一段数构成的数列。
神奇的是小Hi发现了一部名字叫《十进制进行曲大全》的作品集,顾名思义,这部作品集里有许多作品,但是所有的作品有一个共同特征:只用了十个音符,所有的音符都表示成0-9的数字。
现在小Hi想知道这部作品中所有不同的旋律的“和”(也就是把串看成数字,在十进制下的求和,允许有前导0)。答案有可能很大,我们需要对(10^9 + 7)取摸。
输入
第一行,一个整数N,表示有N部作品。
接下来N行,每行包含一个由数字0-9构成的字符串S。
所有字符串长度和不超过 1000000。
输出
共一行,一个整数,表示答案 mod (10^9 + 7)。
Sample Input
2 101 09
Sample Output
131
1 #include<cstring> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstdio> 5 #include<queue> 6 #include<iostream> 7 8 #define ll long long 9 #define N 3000007 10 #define mod 1000000007 11 using namespace std; 12 inline int read() 13 { 14 int x=0,f=1;char ch=getchar(); 15 while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} 16 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();} 17 return x*f; 18 } 19 20 int n; 21 struct sam 22 { 23 int last,cnt; 24 int c[N][11],fa[N],mx[N],flag[N]; 25 sam(){last=cnt=1;} 26 void extend(int x) 27 { 28 int p=last,np=last=++cnt;mx[np]=mx[p]+1; 29 if(x==10)flag[np]=1; 30 while(p&&!c[p][x]) 31 { 32 c[p][x]=np; 33 p=fa[p]; 34 } 35 if(!p)fa[np]=1; 36 else 37 { 38 int q=c[p][x]; 39 if(mx[q]==mx[p]+1)fa[np]=q; 40 else 41 { 42 int nq=++cnt;mx[nq]=mx[p]+1; 43 memcpy(c[nq],c[q],sizeof(c[q])); 44 fa[nq]=fa[q]; 45 fa[q]=fa[np]=nq; 46 while(c[p][x]==q)c[p][x]=nq,p=fa[p]; 47 if(x==10)flag[nq]=1; 48 } 49 } 50 } 51 int du[N],num[N]; 52 void init() 53 { 54 /*for (int i=1;i<=cnt;i++) 55 { 56 for (int j=0;j<=10;j++) 57 if(c[i][j])cout<<c[i][j]<<" "; 58 cout<<endl; 59 }*/ 60 for (int i=1;i<=cnt;i++) 61 for (int j=0;j<=10;j++) 62 if(c[i][j])du[c[i][j]]++; 63 num[1]=1; 64 } 65 int now,pre;queue<int>q[2]; 66 ll sum[N]; 67 void solve() 68 { 69 pre=0,now=1; 70 for (int i=1;i<=cnt;i++) 71 if(!du[i])q[pre].push(i); 72 while(!q[pre].empty()) 73 { 74 while(!q[pre].empty()) 75 { 76 int x=q[pre].front();q[pre].pop(); 77 if(flag[x])sum[x]=0; 78 for (int i=0;i<=10;i++) 79 if(c[x][i]) 80 { 81 // if(c[x][i]==10)cout<<"fack="<<x<<" "<<c[x][i]<<endl; 82 if (!flag[x]) 83 { 84 num[c[x][i]]+=num[x]; 85 (sum[c[x][i]]+=sum[x]*10+num[x]*i)%=mod; 86 } 87 du[c[x][i]]--; 88 if(!du[c[x][i]])q[now].push(c[x][i]); 89 } 90 } 91 swap(now,pre); 92 } 93 /*for (int i=1;i<=cnt;i++) 94 cout<<sum[i]<<endl;*/ 95 ll ans=0; 96 for (int i=1;i<=cnt;i++) 97 (ans+=sum[i])%=mod; 98 printf("%lld\n",ans); 99 } 100 }sam; 101 char s[1000007]; 102 103 int main() 104 { 105 n=read(); 106 for (int i=1;i<=n;i++) 107 { 108 scanf("%s",s+1);int len=strlen(s+1); 109 for (int j=1;j<=len;j++) 110 sam.extend(s[j]-‘0‘); 111 if(i<n)sam.extend(10); 112 } 113 sam.init(); 114 sam.solve(); 115 }