描述
小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 }
来源:oschina
链接:https://my.oschina.net/u/4409656/blog/4054950