bzoj 4545 DQS 的 Trie
老年选手不会 SAM 也不会 LCT 系列
我的数据结构好菜啊 qnq
一颗 Trie 树,$q$ 次询问,每次可以是:
1.求这棵树上本质不同的子串数量
2.插入一个子树,保证总大小不超过 $100000$
3.询问一个字符串在 Trie 树上出现过多少次,保证所有询问串总长度不超过 $100000$
sol:
第一问显然就是个广义 SAM,可以在每次 extend 的时候顺便算出来
第二问和第三问要求动态维护 parent 树的子树 size,差分一下就变成了链加和单点查询,LCT 维护一下即可
注意的几个细节:
如果你要匹配一个整串,串在 SAM 上跑的时候是直接走 Trans 边,不跳 parent
(注意区别于,如果你要匹配一个串的子串,在 SAM 上跑的时候要跳 parent ,注意这两个不一样
LCT 的 link 和 cut,如果你使用的是不 makeroot 的偷懒写法,是不满足交换律的,一定都是一个方向(从上往下 link / cut)
为什么我不 makeroot 啊(平时啥都敢写系列
#include <bits/stdc++.h>
#define LL long long
#define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
using namespace std;
inline int read() {
int x = ,f = ; char ch = getchar();
for(; !isdigit(ch); ch = getchar())if(ch == '-') f = -f;
for(; isdigit(ch); ch = getchar())x = * x + ch - '';
return x * f;
}
const int maxn = ;
#define ls ch[x][0]
#define rs ch[x][1]
char s[maxn];
int n, node[maxn];
int ch[maxn][], fa[maxn], tag[maxn], val[maxn], st[maxn], top;
inline int isroot(int x) { return (ch[fa[x]][] != x) && (ch[fa[x]][] != x); }
inline void rotate(int x) {
int y = fa[x], z = fa[y];
int l = (ch[y][] == x), r = l ^ ;
if(!isroot(y)) ch[z][ch[z][] == y] = x;
fa[x] = z; fa[ch[x][r]] = y; fa[y] = x;
ch[y][l] = ch[x][r]; ch[x][r] = y;
}
inline void pushdown(int x) {
if(x && tag[x]) {
if(ls) tag[ls] += tag[x], val[ls] += tag[x];
if(rs) tag[rs] += tag[x], val[rs] += tag[x];
tag[x] = ;
}
}
inline void splay(int x) {
st[top = ] = x;
for(int i = x; !isroot(i); i = fa[i]) st[++top] = fa[i];
for(int i = top; i; i--) pushdown(st[i]);
while(!isroot(x)) {
int y = fa[x], z = fa[y];
if(!isroot(y)) {
if(ch[y][] == x ^ ch[z][] == y) rotate(x);
else rotate(y);
}
rotate(x);
}
}
inline void access(int x) {
for(int y = ; x; y = x, x = fa[x]) {
splay(x);
rs = y;
}
}
inline void link(int x, int y) {
fa[y] = x; //cerr << "link :" << x << " " << y << endl;
access(x); splay(x);
val[x] += val[y];
tag[x] += val[y];
}
inline void cut(int x, int y) {
access(y); splay(y); //cerr << "cut :" << x << " " << y << endl;
val[x] -= val[y];
tag[x] -= val[y];
fa[x] = ; ch[y][] = ;
}
int tr[maxn][], mxlen[maxn], pre[maxn], root, dfn;
LL ans;
int extend(int last, int c) {
int p = last, np = last = ++dfn;
mxlen[np] = mxlen[p] + ;
for(; p && !tr[p][c]; p = pre[p]) tr[p][c] = np;
if(!p) pre[np] = root, link(root, np);
else {
int q = tr[p][c];
if(mxlen[p] + == mxlen[q]) pre[np] = q, link(q, np);
else {
int nq = ++dfn;
mxlen[nq] = mxlen[p] + ;
pre[nq] = pre[q];
link(pre[q], nq);
memcpy(tr[nq], tr[q], sizeof(tr[nq]));
for(; p && tr[p][c] == q; p = pre[p]) tr[p][c] = nq;
cut(pre[q], q);
pre[np] = pre[q] = nq;
link(pre[q], q);link(pre[np], np);
}
}
ans += ((LL)mxlen[np] - (LL)mxlen[pre[np]]);
access(np); splay(np);
val[np]++; tag[np]++;
// cerr << np << endl;
return np;
}
int first[maxn], to[maxn << ], nx[maxn << ], va[maxn], cnt;
int vis[maxn], clo, par[maxn];
inline void add(int u, int v, int w) {
to[++cnt] = v;
va[cnt] = w;
nx[cnt] = first[u];
first[u] = cnt;
}
void dfs(int x) {
for(int i=first[x];i;i=nx[i]) {
if(to[i] == par[x] || vis[to[i]] != clo) continue;
par[to[i]] = x;
node[to[i]] = extend(node[x], va[i]);
dfs(to[i]);
}
}
int run() {
int now = root, len = strlen(s + );
rep(i, , len) {
// while(now && !tr[now][s[i] - 'a']) now = pre[now];
now = tr[now][s[i] - 'a'];
}
//cerr << now << endl;
if(!now) return ;
access(now); splay(now);
return val[now];
}
int main() {
//freopen("8.in","r",stdin);
//freopen("8oo.out","w",stdout);
//freopen("8oo_err","w",stderr);
root = ++dfn; node[] = root;
read(); n = read(); clo++;
rep(i, , n) {
int u = read(), v = read();
char ch; cin >> ch;
add(u, v, ch - 'a'); add(v, u, ch - 'a');
//cout << ch << endl;
vis[u] = vis[v] = clo;
} dfs();
int q = read();
while(q--) {
int opt = read();
if(opt == ) printf("%lld\n", ans);
else if(opt == ) {
int ri = read(), si = read(); clo++;
rep(i, , si) {
int u = read(), v = read();
char ch; cin >> ch;
add(u, v, ch - 'a'); add(v, u, ch - 'a');
vis[u] = vis[v] = clo;
} dfs(ri);
}
else if(opt == ) {
scanf("%s", s + );
printf("%d\n", run());
}
//int xo = 0;
// rep(i, 1, n) xo ^= node[i];
//cerr << xo << endl;
}
}
bzoj 4545 DQS 的 Trie的更多相关文章
- bzoj 4545: DQS的trie
Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符.并且,它拥有极强的生长力:某个i时刻 ...
- BZOJ4545: DQS的trie
BZOJ4545: DQS的trie https://lydsy.com/JudgeOnline/problem.php?id=4545 分析: 对trie用dfs建sam复杂度是\(O(n^2)\) ...
- 【BZOJ4545】DQS的trie 后缀自动机+LCT
[BZOJ4545]DQS的trie Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符 ...
- BZOJ 4545
bzoj 4545 给定一个踹树,支持几种操作. 本质不同子串询问 加入子树 询问字符串\(S\) 在树上的出现次数. 好码好码 重点就是维护\(parent\) 树,考虑用\(LCT\)维护此树. ...
- BZOJ 4260: Codechef REBXOR( trie )
求出前缀和, 那么以第x个元素结尾的最大异或值是max(sumx^sump)(1≤p<x), 用trie加速. 后缀同理, 然后扫一遍就OK了.时间复杂度O(31N) ------------- ...
- BZOJ 3689 异或 Trie木+堆
标题效果:特定n的数量,这种需求n数22 XOR的值前者k少 首先,我们建立了一个二进制的所有数字Trie木,您可以使用Trie木size域检查出一些其他的数字XOR值首先k少 然后,我们要保持一个堆 ...
- bzoj 2741 可持久化trie
首先我们设si为前i个数的xor和,那么对于询问区间[i,j]的xor和,就相当于si-1^sj,那么对于这道题的询问我们可以处理处si,然后对于询问[l,r],可以表示为在区间[l-1,r]里找两个 ...
- BZOJ - 3166 可持久化Trie 维护次大区间
题意:给出\(a[1...n]\),找出一个连续区间\(a[l...r],r>l\),令该区间的次大值为\(a_k\),使得\(a_k⊕a_i,l≤i≤r\)最大,输出全局最优解 (这题意有点别 ...
- bzoj 1819: 电子字典 Trie
题目: Description 人们在英文字典中查找某个单词的时候可能不知道该单词的完整拼法,而只知道该单词的一个错误的近似拼法,这时人们可能陷入困境,为了查找一个单词而浪费大量的时间.带有模糊查询功 ...
随机推荐
- 使用Socket&反射&Java流操作进行方法的远程调用(模拟RPC远程调用)
写在前面 阅读本文首先得具备基本的Socket.反射.Java流操作的基本API使用知识:否则本文你可能看不懂... 服务端的端口监听 进行远程调用,那就必须得有客户端和服务端.服务端负责提供服务,客 ...
- Spark机器学习4·分类模型(spark-shell)
线性模型 逻辑回归--逻辑损失(logistic loss) 线性支持向量机(Support Vector Machine, SVM)--合页损失(hinge loss) 朴素贝叶斯(Naive Ba ...
- spring配置中classpath: 与classpath*:的区别
classpath和classpath*区别: classpath:只会到你的class路径中查找找文件. classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找 ...
- app自动化测试-appium
一.环境准备(windows) 1.安装Microsoft .NET Framework 4.5 双击运行如下文件:net4.5.1.exe 2.安装node-v6.11.4-x64.msi 双击运行 ...
- article标准用法
article代表一个在文档.页面或者网站中自成一体的内容 其目的是为了让开或重用 譬如论坛的帖子.博客的文章.一片用户的评论.一个互动的widget小工具 article 会有一个标题(通常在hea ...
- 强大的jQuery幻灯片播放插件 支持全拼、拖拽和下载等功能
在线演示 本地下载
- RN项目中缩进处理
SpannableString使用详解http://blog.csdn.net/u012702547/article/details/49895157 Spannable的用法http://www.j ...
- 不同vlan间通信的三种配置方式
1.单臂路由(图) 环境:一台路由器,一台二层交换机,两台pc机 二层交换机的配置 //创建vlan 和 vlan : Switch(config)#vlan Switch(config-vlan)# ...
- CentOS 7安装Xfce和VNC
很多VPS商提供的CentOS 7镜像只有最小化安装,这样就只能在命令行下操作,如果要调试代码的话,还是图形化界面方便,而且CentOS自带的Gnome和KDE都比较占内存.启动桌面后就占用了400M ...
- maven编译时GBK错误
一.问题描述 今天在MyEclipse中使用Maven编译项目源代码时,结果如下了如下的错误 百思不得其解啊,Java源代码在MyEclipse中显示是没有任何错误的,可是执行"maven ...