# HihoCoder - 1457 后缀自动机四·重复旋律7 后缀自动机+拓扑排序+递推、BFS

☺藏题阁☺ 同时被 3 个专栏收录
129 篇文章 0 订阅
9 篇文章 0 订阅
5 篇文章 0 订阅

# 后缀自动机四·重复旋律7

#### 输出

2
101
09

131

Source

My Solution

#include <iostream>
#include <cstdio>
#include <string>
#include <queue>
#include <cstring>
using namespace std;
typedef long long LL;
typedef pair<int, int> ii;
const int MAXN = 2*1e6 + 8;
const LL MOD = 1e9 + 7;

string s;
struct SAM{
int ch[MAXN][12], pre[MAXN], val[MAXN];
int last, tot;
void init(){
last = tot = 0;
memset(ch[0], -1, sizeof ch[0]);
pre[0] = -1; val[0] = 0;
}
void extend(int c){
int p = last, np = ++tot;
val[np] = val[p] + 1;
memset(ch[np], -1, sizeof ch[np]);
while(~p && ch[p][c] == -1) ch[p][c] = np, p = pre[p];
if(p == -1) pre[np] = 0;
else{
int q = ch[p][c];
if(val[q] != val[p] + 1){
int nq = ++tot;
memcpy(ch[nq], ch[q], sizeof ch[q]);
val[nq] = val[p] + 1;
pre[nq] = pre[q];
pre[q] = pre[np] = nq;
while(~p && ch[p][c] == q) ch[p][c] = nq, p = pre[p];
}
else pre[np] = q;
}
last = np;
}

//get_ans
int deg[MAXN];
LL cnt[MAXN], validsubstr[MAXN];
queue<ii> que;
LL mod(LL x){
return x - x / MOD * MOD;
}
LL sum = 0;
string str;
void bfs(){
int fa, u, v, sz, i;
LL validsubstring;
validsubstr[0] = 1;
sz = 11;
while(!que.empty()){
u = que.front().first;
fa = que.front().second;
que.pop();
for(i = 0; i < sz; i++){
v = ch[u][i];
if(v == fa) continue;
if(v == -1) continue;
deg[v]--;
validsubstring = i == 10 ? 0 : validsubstr[u];
validsubstr[v] = mod(validsubstr[v] + validsubstring);
if(validsubstring > 0) cnt[v] = mod(cnt[v] + mod(cnt[u]*10) + validsubstring * i);
if(deg[v] == 0){
que.push(ii(v, u));
sum = mod(sum + cnt[v]);
}
}
}
}
void get_deg(){
int i, j;
for(i = 0; i <= tot; i++){
for(j = 0; j <= 10; j++){
if(ch[i][j] != -1) deg[ch[i][j]]++;
}
}
}
void get_ans(){
memset(deg, 0, sizeof deg);
memset(cnt, 0, sizeof cnt);
memset(validsubstr, 0, sizeof validsubstr);
int n, i, j, sz;
cin >> n;
cin >> s;
for(i = 1; i < n; i++){
cin >> str;
s += ':';
s += str;
}
//cout << (':' - '0') << endl;  //(':' - '0') == 10
sz = s.size();
init();
for(i = 0; i < sz; i++) extend(s[i] - '0');
get_deg();
que.push(ii(0, -1));
bfs();
cout << sum << endl;
}

} sam;

int main()
{
#ifdef LOCAL
freopen("23.in", "r", stdin);
//freopen("23.out", "w", stdout);
int T = 1;
while(T--){
#endif // LOCAL
ios::sync_with_stdio(false); cin.tie(0);

sam.get_ans();

#ifdef LOCAL
cout << endl;
}
#endif // LOCAL
return 0;
}


Thank you!

------from ProLights

• 0
点赞
• 0
评论
• 0
收藏
• 一键三连
• 扫一扫，分享海报

02-02 178

03-18 321
02-03 468
01-07 463
04-28 37
04-02 156
12-23 52
10-20 1070
10-03 458
09-20 84
01-22 51