HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1001-string string string
2017-09-12 16:57
531 查看
ACM模版
建立后缀自动机后,对每个节点统计出现次数,然后对字符串的后缀进行加一,更新每个节点的父节点就好了。
描述
题解
后缀自动机……我知识的盲区,学过 AC 自动机,后缀数组,等等算法,就是没有学过这个……怪不得做不出来。建立后缀自动机后,对每个节点统计出现次数,然后对字符串的后缀进行加一,更新每个节点的父节点就好了。
代码
#include <iostream> #include <cstring> using namespace std; typedef long long ll; const int MAXN = 2e5 + 10; const int MAGIC = 26; class SAM { public: int n; int last, tot; char s[MAXN]; int c[MAXN]; int q[MAXN]; int pre[MAXN]; int cnt[MAXN]; int len[MAXN]; int step[MAXN]; int son[MAXN][MAGIC + 1]; void clear(char *_s) { n = (int)strlen(_s); memcpy(s, _s, sizeof(char) * (n + 5)); int t = (n << 1) + 10; for (int i = 0; i < t; i++) { for (int j = 0; j < MAGIC; j++) { son[i][j] = 0; } pre[i] = step[i] = 0; } last = tot = 0; } void extend(char ch) { step[++tot] = step[last] + 1; int p = last, np = tot; for (; !son[p][ch]; p = pre[p]) { son[p][ch] = np; } if (!p) { pre[np] = 1; } else { int q = son[p][ch]; if (step[q] == step[p] + 1) { pre[np] = q; } else { step[++tot] = step[p] + 1; int nq = tot; memcpy(son[nq], son[q], sizeof(son[q])); pre[nq] = pre[q]; pre[q] = pre[np] = nq; for (; son[p][ch] == q; p = pre[p]) { son[p][ch] = nq; } } } last = np; cnt[last]++; } void build() { int t = (n << 1) + 10; for (int i = 0; i < t; i++) { cnt[i] = 0; } last = tot = 1; for (int i = 0; i < n; i++) { extend(s[i] - 'a'); } } void calc(int k) { int t = (n << 1) + 10; for (int i = 0; i < t; i++) { c[i] = 0; } for (int i = 1; i <= tot; i++) { c[step[i]]++; } for (int i = 1; i <= tot; i++) { c[i] += c[i - 1]; } for (int i = 1; i <= tot; i++) { q[c[step[i]]--] = i; } ll ans = 0; for (int i = tot; i; i--) { int u = q[i]; if (pre[u] > 0) { cnt[pre[u]]+=cnt[u]; } if (cnt[u] == k) { ans += step[u] - step[pre[u]]; } } printf("%lld\n",ans); } } S; int k; char s[MAXN]; int main() { int T; scanf("%d", &T); while (T--) { scanf("%d%s", &k, s); S.clear(s); S.build(); S.calc(k); } return 0; }
相关文章推荐
- HDU 6194 String String String (后缀数组+线段树, 2017 ACM/ICPC Asia Regional Shenyang Online)
- 2017 ACM/ICPC Asia Regional Shenyang Online 1001(hdu 6194)
- HDU 6203 ping ping ping (LCA + 树状数组, 2017 ACM/ICPC Asia Regional Shenyang Online)
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1008-transaction transaction transaction
- HDU-2017 ACM/ICPC Asia Regional Qingdao Online-1001-Apple
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1012-card card card
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-签到题
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1002-cable cable cable
- HDU 6201 transaction transaction transaction (Dijstra, 2017 ACM/ICPC Asia Regional Shenyang Online)
- 【2017 ACM/ICPC Asia Regional Shenyang Online 1005】hdu 6198 number number number
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1004-array array array
- 2017 ACM/ICPC Asia Regional Shenyang Online//string string string(后缀自动机,未学习)
- HDU - 6205 card card card (贪心)2017 ACM/ICPC Asia Regional Shenyang Online
- HDU 6199 gems gems gems (DP, 2017 ACM/ICPC Asia Regional Shenyang Online)
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-1005-number number number
- 【2017 ACM/ICPC Asia Regional Shenyang Online 1002】hdu 6195 cable cable cable
- 2017 ACM/ICPC Asia Regional Shenyang Online 1004 array array array
- HDU 6216 A Cubic number and A Cubic Number 公式/打表 [2017 ACM/ICPC Asia Regional Qingdao Online]
- hdu 5461 Largest Point 2015 ACM/ICPC Asia Regional Shenyang Online
- 2017 ACM/ICPC Asia Regional Shenyang Online card