P5840 [COCI2015]Divljak
// powered by c++11
// by Isaunoya
#include <bits/stdc++.h>
#define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
#define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
using namespace std;
using db = double;
using ll = long long;
using uint = unsigned int;
#define int long long
using pii = pair<int, int>;
#define ve vector
#define Tp template
#define all(v) v.begin(), v.end()
#define sz(v) ((int)v.size())
#define pb emplace_back
#define fir first
#define sec second
// the cmin && cmax
Tp<class T> void cmax(T& x, const T& y) {
if (x < y) x = y;
}
Tp<class T> void cmin(T& x, const T& y) {
if (x > y) x = y;
}
// sort , unique , reverse
Tp<class T> void sort(ve<T>& v) { sort(all(v)); }
Tp<class T> void unique(ve<T>& v) {
sort(all(v));
v.erase(unique(all(v)), v.end());
}
Tp<class T> void reverse(ve<T>& v) { reverse(all(v)); }
const int SZ = 0x191981;
struct FILEIN {
~FILEIN() {}
char qwq[SZ], *S = qwq, *T = qwq, ch;
char GETC() { return (S == T) && (T = (S = qwq) + fread(qwq, 1, SZ, stdin), S == T) ? EOF : *S++; }
FILEIN& operator>>(char& c) {
while (isspace(c = GETC()))
;
return *this;
}
FILEIN& operator>>(string& s) {
while (isspace(ch = GETC()))
;
s = ch;
while (!isspace(ch = GETC())) s += ch;
return *this;
}
Tp<class T> void read(T& x) {
bool sign = 1;
while ((ch = GETC()) < 0x30)
if (ch == 0x2d) sign = 0;
x = (ch ^ 0x30);
while ((ch = GETC()) > 0x2f) x = x * 0xa + (ch ^ 0x30);
x = sign ? x : -x;
}
FILEIN& operator>>(int& x) { return read(x), *this; }
FILEIN& operator>>(signed& x) { return read(x), *this; }
FILEIN& operator>>(unsigned& x) { return read(x), *this; }
} in;
struct FILEOUT {
const static int LIMIT = 0x114514;
char quq[SZ], ST[0x114];
signed sz, O;
~FILEOUT() { flush(); }
void flush() {
fwrite(quq, 1, O, stdout);
fflush(stdout);
O = 0;
}
FILEOUT& operator<<(char c) { return quq[O++] = c, *this; }
FILEOUT& operator<<(string str) {
if (O > LIMIT) flush();
for (char c : str) quq[O++] = c;
return *this;
}
Tp<class T> void write(T x) {
if (O > LIMIT) flush();
if (x < 0) {
quq[O++] = 0x2d;
x = -x;
}
do {
ST[++sz] = x % 0xa ^ 0x30;
x /= 0xa;
} while (x);
while (sz) quq[O++] = ST[sz--];
return;
}
FILEOUT& operator<<(int x) { return write(x), *this; }
FILEOUT& operator<<(signed x) { return write(x), *this; }
FILEOUT& operator<<(unsigned x) { return write(x), *this; }
} out;
int n, q;
const int maxn = 2e6 + 62;
int ch[maxn][26], cnt = 1, ed[maxn], fail[maxn];
int ins(string s) {
int p = 1;
for (char c : s) {
int x = c - 'a';
if (!ch[p][x]) ch[p][x] = ++cnt;
p = ch[p][x];
}
return p;
}
void buildfail() {
queue<int> q;
for (int i = 0; i < 26; i++)
if (ch[1][i])
fail[ch[1][i]] = 1, q.push(ch[1][i]);
else
ch[1][i] = 1;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = 0; i < 26; i++)
if (ch[u][i])
fail[ch[u][i]] = ch[fail[u]][i], q.push(ch[u][i]);
else
ch[u][i] = ch[fail[u]][i];
}
}
vector<int> g[maxn];
int sz[maxn], d[maxn], son[maxn];
void dfs(int u) {
sz[u] = 1;
for (int v : g[u]) {
d[v] = d[u] + 1;
dfs(v), sz[u] += sz[v];
if (sz[v] > sz[son[u]]) son[u] = v;
}
}
int dfn[maxn], idx = 0, top[maxn];
void dfs(int u, int t) {
top[u] = t, dfn[u] = ++idx;
if (son[u]) dfs(son[u], t);
for (int v : g[u])
if (v ^ son[u]) dfs(v , v);
}
int lca(int u, int v) {
while (top[u] ^ top[v]) {
if (d[top[u]] < d[top[v]]) u ^= v ^= u ^= v;
u = fail[top[u]];
// fa_u = fail_u
}
return d[u] < d[v] ? u : v;
}
// bit
int c[maxn];
int low(int x) { return x & -x; }
void upd(int x, int y) {
for (; x <= cnt; x += low(x)) c[x] += y;
}
int qry(int x) {
int ans = 0;
for (; x; x ^= low(x)) ans += c[x];
return ans;
}
signed main() {
#ifdef _WIN64
freopen("testdata.in", "r", stdin);
#else
ios_base ::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
#endif
// code begin.
in >> n;
rep(i, 1, n) {
string s;
ed[i] = ins((in >> s, s));
}
buildfail();
rep(i, 2, cnt) g[fail[i]].pb(i);
dfs(1), dfs(1, 1);
in >> q;
while (q--) {
int op;
in >> op;
if (op == 1) {
string s;
in >> s;
int p = 1;
vector<int> P;
for (char c : s) {
int x = c - 'a';
p = ch[p][x], P.pb(p);
}
sort(P.begin() , P.end() , [](int x, int y) { return dfn[x] < dfn[y]; });
P.erase(unique(P.begin() , P.end()) , P.end()) ;
for (int i = 0; i < sz(P); i++) {
upd(dfn[P[i]], 1);
if (i) upd(dfn[lca(P[i - 1] , P[i])], -1);
}
} else {
int x;
out << (in >> x , qry(dfn[ed[x]] + sz[ed[x]] - 1) - qry(dfn[ed[x]] - 1)) << '\n' ;
}
}
return 0;
// code end.
}
P5840 [COCI2015]Divljak的更多相关文章
- BZOJ 3881: [Coci2015]Divljak [AC自动机 树链的并]
3881: [Coci2015]Divljak 题意:添加新文本串,询问某个模式串在多少种文本串里出现过 模式串建AC自动机,考虑添加一个文本串,走到的节点记录下来求树链的并 方法是按dfs序排序去重 ...
- BZOJ 3881: [Coci2015]Divljak
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 553 Solved: 176[Submit][Sta ...
- 【BZOJ3881】[Coci2015]Divljak fail树+树链的并
[BZOJ3881][Coci2015]Divljak Description Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操 ...
- BZOJ3881 : [Coci2015]Divljak
对Alice的所有串构造AC自动机,并建出Fail树 每当Bob添加一个串时,在AC自动机上走,每走到一个点,就把它到根路径上所有点的答案+1 需要注意的是每次操作,相同的点只能被加一次 所以在需要操 ...
- [Coci2015]Divljak
题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...
- BZOJ3881[Coci2015]Divljak——AC自动机+树状数组+LCA+dfs序+树链的并
题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...
- 【bzoj3881】[Coci2015]Divljak AC自动机+树链的并+DFS序+树状数组
题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...
- BZOJ3881 Coci2015 Divljak fail树+差分
题目大意,给出两个字符串集合S和T,向T中添加字符串,查询S_i在T中有几个字符串出现过.一看这种多字符串匹配问题,我们联想到了AC自动机,做法就是,对于S集合我们建立一个AC自动机,建出fail树, ...
- bzoj 3881: [Coci2015]Divljak AC自动机
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3881 题解: 这道题我想出了三种做法,不过只有最后一种能过. 第一种: 首先我们把所有的 ...
随机推荐
- BOM DOM 注意事項
setTimeout(js,時間) js处 应该放一个函数 不能放 alert confirm 等 (否则延时会失效) setTimeout() 和 setInterval() 的区别: ...
- systemctl中添加mysql服务
由于mysql的版本更新,许多术语有了新含义,所以需要特别指出,mysqld.service 等价于mysqld vim /usr/lib/systemd/system/mysqld.service ...
- [GPU高性能编程CUDA实战].(桑德斯).聂雪军等.扫描版-百度云分享
链接:https://pan.baidu.com/s/1NkkDiyRgmfmhm9d2g_GBKQ 提取码:3usj
- Linux防火墙之iptables常用扩展匹配条件(二)
上一篇博文我们讲到了iptables的一些常用的扩展匹配模块以及扩展模块的一些选项的说明,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12273755.htm ...
- ROS和Gazebo进行机器人仿真(二)
一.在Gazebo中使用ROS控制器 在本节中,我们将讨论如何在Gazebo中让机器人的每个关节运动. 为了让关节动起来,我们需要分配一个ROS控制器,尤其是,我们需要为每个关节连上一个与transm ...
- Rancher2.x 一键式部署 Prometheus + Grafana 监控 Kubernetes 集群
目录 1.Prometheus & Grafana 介绍 2.环境.软件准备 3.Rancher 2.x 应用商店 4.一键式部署 Prometheus 5.验证 Prometheus + G ...
- 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器
===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...
- PAT基础编程练习
7-1 厘米换算英尺英寸 (15 分) 如果已知英制长度的英尺foot和英寸inch的值,那么对应的米是(.现在,如果用户输入的是厘米数,那么对应英制长度的英尺和英寸是多少呢?别忘了1英尺等于12 ...
- Java 代码实现链表
Linked List 用多少就申请多少内存. 链表是一种链式存储的线性表,所有元素的内存地址不一定连续的. 接口设计 代码实现 MyList.java(接口) package com.cyb; pu ...
- Nginx+uWSGI+Django原理(转发)
Python的Web开发中,如果使用Django框架,那么较为成熟稳定的服务器架构一般是Nginx+uWSGI+Django.而为什么一定要三个结合在一起呢?直接使用Django的runserver来 ...