后缀自动机四·重复旋律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] = '';
84         for(int i = 0; i < pos; i++) sa(s[i]);
85         ans = 0;
86         cal();
87         printf("%lld
", ans);
88     }
89 }
View Code
原文地址:https://www.cnblogs.com/yijiull/p/8508189.html