【NOI2017模拟6.2】字符串
来源:互联网 发布:卡是3g的手机是2g网络 编辑:程序博客网 时间:2024/05/14 23:05
Description:
1<=n<=10^6,1<=
题解:
不同子串肯定和后缀自动机有关。
对每个串搞出后缀自动机。
关键在于如何合并这些玩意。
倒着做。
设
可以枚举它的下一个字符是什么,如果自动机里有边,就可以直接走过去传递。
如果没有,可以找到后面的自动机中第一个root有这个字符的对应的状态,从那里转移。
答案就是所以最后出现的字符的对应状态的f的sum。
Code:
#include<cstdio> #include<cstring>#define fo(i, x, y) for(int i = x; i <= y; i ++)#define fd(i, x, y) for(int i = x; i >= y; i --)using namespace std;const int N = 2e6 + 5;const int mo = 1e9 + 7;int f[N], lat[26];struct suffix_automation { int last, tot, fa[N], to[N][26], dep[N]; #define push(v) dep[++ tot] = v; void Extend(int st, int c) { push(dep[last] + 1); int p = last, np = tot; for(; p && !to[p][c]; p = fa[p]) to[p][c] = np; if(!p) fa[np] = st; else { int q = to[p][c]; if(dep[p] + 1 < dep[q]) { push(dep[p] + 1); int nq = tot; memcpy(to[nq], to[q], sizeof to[q]); fa[nq] = fa[q]; fa[q] = fa[np] = nq; for(; to[p][c] == q; p = fa[p]) to[p][c] = nq; } else fa[np] = q; } last = np; } int d[N], ff[N], r[N]; void bfs(int x, int y) { int st = 1, en = 0; fo(i, x, y) fo(j, 0, 25) if(to[i][j]) r[to[i][j]] ++; fo(i, x, y) if(!r[i]) d[++ en] = i; for(; st <= en; st ++) { int x = d[st]; fo(j, 0, 25) if(to[x][j] && !(-- r[to[x][j]])) d[++ en] = to[x][j]; } fd(i, en, 1) { int x = d[i]; f[x] = 1; fo(i, 0, 25) if(to[x][i]) f[x] = (f[x] + f[to[x][i]]) % mo; else f[x] = (f[x] + f[lat[i]]) % mo; } }} suf;int n; char s[N];int st[N], en[N], ans;int main() { freopen("str.in", "r", stdin); freopen("str.out", "w", stdout); scanf("%d", &n); fo(i, 1, n) { scanf("%s", s + 1); int len = strlen(s + 1); suf.last = suf.tot = st[i] = en[i - 1] + 1; fo(j, 1, len) suf.Extend(st[i], s[j] - 'a'); en[i] = suf.tot; } fd(i, n, 1) { suf.bfs(st[i], en[i]); fo(j, 0, 25) if(suf.to[st[i]][j]) lat[j] = suf.to[st[i]][j]; } fo(k, 0, 25) ans = (ans + f[lat[k]]) % mo; printf("%d", (ans + 1) % mo);}
阅读全文
1 0
- 【NOI2017模拟6.2】字符串
- 【NOI2017模拟4.5】无限棋盘【哈希,字符串,倍增】
- NOI2017模拟3.1 总结
- NOI2017模拟3.8 总结
- 【NOI2017模拟3.30】原谅
- 【NOI2017模拟4.2】查询
- 【NOI2017模拟4.2】押韵
- 【NOI2017模拟6.26】A
- 【NOI2017模拟6.29】呵呵
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- [JZOJ100003]【NOI2017模拟.4.1】 Tree
- 【JZOJ5036】【NOI2017模拟3.30】原谅
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- 【JZOJ5040】【NOI2017模拟4.2】押韵
- 【JZOJ5039】【NOI2017模拟4.2】查询
- 【JZOJ100003】【NOI2017模拟.4.1】 Tree
- 【JZOJ100004】【NOI2017模拟.4.1】 Dice
- [JZOJ100004]【NOI2017模拟.4.1】 Dice
- linux下的网络编程(转载文章链接)
- java源码学习(一)
- sqlmap数据转中文字符串
- PRML系列:1.5 Decision Theory
- 《看透SpringMVC源码》笔记之总结
- 【NOI2017模拟6.2】字符串
- 用IOT的思维来管理我们的查看我们重要业务的服务器健康状态-实现IOT设备远端控制!
- Docker+Jenkins_自动化持续集成
- 不了解Java虚拟机的小伙伴看这一本书就够了!
- tinyxml2的使用
- CentOS7上部署搭建Kafka集群
- redis的两种持久化
- 以LeNet为例分析CNN中的参数量
- 在Ubuntu下安装Python3.6.0