bzoj4545
lct+SAM
bzoj4516+bzoj2555
这道题唯一的用处就是教会了我真正的广义SAM
dfs时保留当前节点在后缀自动机中的位置,每个点接着父亲建
lct动态维护right集合大小,用lct维护子树就行了
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int N = 1e5 + ;
- struct edge {
- int nxt, to, w;
- } e[N << ];
- int n, m, cnt = ;
- int h[N], pos[N];
- char s[N];
- long long sum;
- namespace lct
- {
- struct node {
- int ch[];
- int f, tag, reg;
- } t[N << ];
- bool isr(int x) {
- return !t[x].f || (t[t[x].f].ch[] != x && t[t[x].f].ch[] != x);
- }
- int wh(int x) {
- return x == t[t[x].f].ch[];
- }
- void paint(int x, int d) {
- t[x].tag += d;
- t[x].reg += d;
- }
- void pushdown(int x) {
- if(t[x].tag) {
- paint(t[x].ch[], t[x].tag);
- paint(t[x].ch[], t[x].tag);
- t[x].tag = ;
- }
- }
- void pd(int x) {
- if(!isr(x)) {
- pd(t[x].f);
- }
- pushdown(x);
- }
- void rotate(int x) {
- int y = t[x].f, z = t[y].f, w = wh(x);
- if(!isr(y)) {
- t[z].ch[wh(y)] = x;
- }
- t[x].f = z;
- t[y].ch[w] = t[x].ch[w ^ ];
- t[t[x].ch[w ^ ]].f = y;
- t[y].f = x;
- t[x].ch[w ^ ] = y;
- }
- void splay(int x) {
- pd(x);
- for(; !isr(x); rotate(x)) {
- if(!isr(t[x].f)) {
- rotate(wh(t[x].f) == wh(x) ? t[x].f : x);
- }
- }
- }
- void access(int x) {
- for(int y = ; x; y = x, x = t[x].f) {
- splay(x);
- t[x].ch[] = y;
- }
- }
- void link(int u, int v) {
- access(u);
- splay(u);
- access(v);
- splay(v);
- paint(v, t[u].reg);
- t[u].f = v;
- }
- void cut(int u, int v) {
- access(u);
- splay(u);
- t[u].ch[] = ;
- t[v].f = ;
- paint(v, -t[u].reg);
- }
- }
- namespace SAM
- {
- struct node {
- int ch[];
- int par, val;
- } t[N << ];
- int root = , sz = ;
- int nw(int x) {
- t[++sz].val = x;
- return sz;
- }
- int extend(int last, int c) {
- int p = last, np = nw(t[p].val + );
- lct::t[np].reg = ;
- while(p && !t[p].ch[c]) {
- t[p].ch[c] = np;
- p = t[p].par;
- }
- if(!p) {
- t[np].par = root;
- lct::link(np, root);
- } else {
- int q = t[p].ch[c];
- if(t[q].val == t[p].val + ) {
- t[np].par = q;
- lct::link(np, q);
- } else {
- int nq = nw(t[p].val + );
- lct::link(nq, t[q].par);
- lct::cut(q, t[q].par);
- lct::link(np, nq);
- lct::link(q, nq);
- t[nq].par = t[q].par;
- t[np].par = t[q].par = nq;
- memcpy(t[nq].ch, t[q].ch, sizeof(t[q].ch));
- while(p && t[p].ch[c] == q) {
- t[p].ch[c] = nq;
- p = t[p].par;
- }
- }
- }
- sum += t[np].val - t[t[np].par].val;
- return np;
- }
- void solve(char *s) {
- int len = strlen(s), now = root;
- for(int i = ; i < len; ++i) {
- if(!t[now].ch[s[i] - 'a']) {
- puts("");
- return;
- }
- now = t[now].ch[s[i] - 'a'];
- }
- lct::pd(now);
- printf("%d\n", lct::t[now].reg);
- lct::splay(now);
- }
- }
- void link(int u, int v, int w) {
- e[++cnt].nxt = h[u];
- h[u] = cnt;
- e[cnt].to = v;
- e[cnt].w = w;
- }
- void dfs(int u, int last) {
- for(int i = h[u]; i; i = e[i].nxt) {
- if(e[i].to == last) {
- continue;
- }
- pos[e[i].to] = SAM::extend(pos[u], e[i].w);
- dfs(e[i].to, u);
- }
- h[u] = ;
- }
- int main() {
- // freopen("1.out", "w", stdout);
- int laji;
- scanf("%d%d", &laji, &n);
- for(int i = ; i < n; ++i) {
- int u, v;
- scanf("%d%d%s", &u, &v, s);
- link(u, v, s[] - 'a');
- link(v, u, s[] - 'a');
- }
- pos[] = ;
- dfs(, );
- scanf("%d", &m);
- while(m--) {
- int opt;
- scanf("%d", &opt);
- if(opt == ) {
- printf("%lld\n", sum);
- } else if(opt == ) {
- int rt, sz;
- scanf("%d%d", &rt, &sz);
- while(--sz) {
- int u, v;
- scanf("%d%d%s", &u, &v, s);
- link(u, v, s[] - 'a');
- link(v, u, s[] - 'a');
- }
- dfs(rt, );
- } else {
- scanf("%s", s);
- SAM::solve(s);
- }
- }
- return ;
- }
bzoj4545的更多相关文章
- 【BZOJ4545】DQS的trie 后缀自动机+LCT
[BZOJ4545]DQS的trie Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符 ...
- BZOJ4545: DQS的trie
BZOJ4545: DQS的trie https://lydsy.com/JudgeOnline/problem.php?id=4545 分析: 对trie用dfs建sam复杂度是\(O(n^2)\) ...
- BZOJ4545: DQS的trie 广义后缀自动机_LCT
特别鸣神犇 fcwww 替我调出了无数个错误(没他的话我都快自闭了),祝大佬省选rp++ 板子题,给我写了一天QAQ...... 用 LCT 维护后缀树,暴力更新用 LCT 区间更新链即可 其实,在计 ...
随机推荐
- PAT 1057. 数零壹(20)
给定一串长度不超过105的字符串,本题要求你将其中所有英文字母的序号(字母a-z对应序号1-26,不分大小写)相加,得到整数N,然后再分析一下N的二进制表示中有多少0.多少1.例如给定字符串“PAT ...
- ACM-最小生成树之继续畅通project——hdu1879
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/lx417147512/article/details/27092583 ************** ...
- eclipse 修改 JDK中的src.zip的路径
http://blog.sina.com.cn/s/blog_54a1bca7010112fb.html http://www.douban.com/note/211369821/ 1.点 “wind ...
- 查询某个字段为null并且某个字段不为null的数据
查询代码为null且ggid不为null的公司名 select name_of_invested_company from dwtz WHERE code is NULL and ggid is no ...
- 更改node版本
npm install -g n n stable 或 n v4.5.0
- 开发rsync启动脚本
rsync rsync是类unix系统下的数据镜像备份工具——remote sync.一款快速增量备份工具 Remote Sync,远程同步 支持本地复制,或者与其他SSH.rsync主机同步. ...
- <再看TCP/IP第一卷>TCP/IP协议族中的最压轴戏----TCP协议及细节
题外话:刚刚过去的半个月实在是忙得我喘不过来气,虽然手里还压着几个项目得在期末考试之前做完,但是想想还是更新一下随笔,稍微换个心情.另外小吐槽一下那些在博客园里原封不动抄书当随笔的人,唉真是....算 ...
- Luogu-2657 [SCOI2009]windy数
很少做数位\(dp\)的题,做道题学习一下吧. 记忆化搜索,\(f[10][10][2][2]\)分别记录当前位置,上一位数,是否有前导零和是否有大小上限. 题目要满足相邻两个数相差不小于2,如果有前 ...
- MSSQL遇到以零作除数错误的处理方法
在sql server中做除法处理的时候,我们经常需要处理除数为零的情况,因为如果遇到这种情况的时候,sqlserver会抛出遇到以零作除数错误的异常,我们总不希望把这个异常显示给用户吧. 做个会报这 ...
- Oracle的PL_SQL的异常处理
--什么是异常 --异常是在PL/SQL运行过程中有可能出现的错误. --执行异常的语句 exception when [异常] when --异常输出信息. --Oracle的预定义异常 CASE_ ...