后缀自动机四·重复旋律7
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 2000010; 4 const int mod = 1e9 + 7; 5 char s[maxn]; 6 int len[maxn<<1], tr[maxn<<1][11], link[maxn<<1]; 7 int sz, last; 8 void init(){ 9 sz = last = 0; 10 len[0] = 0, link[0] = -1; 11 memset(tr, -1, sizeof tr); 12 ++sz; 13 } 14 void sa(int c){ 15 c = c - '0'; 16 int cur = sz++; 17 len[cur] = len[last] + 1; 18 int p; 19 for(p = last; ~p && tr[p][c] == -1; p = link[p]){ 20 tr[p][c] = cur; 21 } 22 if(p == -1) link[cur] = 0; 23 else{ 24 int q = tr[p][c]; 25 if(len[p] + 1 == len[q]) link[cur] = q; 26 else{ 27 int co = sz++; 28 len[co] = len[p] + 1; 29 for(int i = 0; i < 10; i++) tr[co][i] = tr[q][i]; 30 link[co] = link[q]; 31 for(; ~p && tr[p][c] == q; p = link[p]) tr[p][c] = co; 32 link[q] = link[cur] = co; 33 } 34 } 35 last = cur; 36 } 37 long long ans; 38 int ind[maxn<<1], vis[maxn<<1]; 39 int cnt[maxn<<1], sum[maxn<<1]; 40 void cal(){ 41 queue<int> q; 42 memset(vis, 0, sizeof vis); 43 memset(ind, 0, sizeof ind); 44 q.push(0); 45 vis[0] = 1; 46 while(!q.empty()){ 47 int u = q.front(); q.pop(); 48 for(int i = 0; i < 10; i++){ 49 if(tr[u][i] != -1) ind[tr[u][i]]++; 50 if(!vis[tr[u][i]]){ 51 vis[tr[u][i]] = 1; 52 q.push(tr[u][i]); 53 } 54 } 55 } 56 cnt[0] = 1, sum[0] = 0; 57 q.push(0); 58 while(!q.empty()){ 59 int u = q.front(); q.pop(); 60 for(int i = 0; i < 10; i++) { 61 int v = tr[u][i]; 62 if(v != -1){ 63 cnt[v] += cnt[u]; 64 sum[v] = (sum[v] + sum[u] * 10LL % mod + i * cnt[u]) % mod; 65 ind[v]--; 66 if(!ind[v]) q.push(v); 67 } 68 } 69 } 70 for(int i = 0; i < sz; i++) ans = (ans + sum[i]) % mod; 71 } 72 int main(){ 73 int n; 74 while(scanf("%d", &n) != EOF){ 75 init(); 76 int pos = 0; 77 for(int i = 0; i < n; i++){ 78 scanf("%s", s + pos); 79 pos += strlen(s + pos); 80 s[pos] = ':'; 81 pos++; 82 } 83 s[--pos] = '\0'; 84 for(int i = 0; i < pos; i++) sa(s[i]); 85 ans = 0; 86 cal(); 87 printf("%lld\n", ans); 88 } 89 }