bzoj 2434 AC自动机 + fail指针建树 + 树状数组
思路:我们先跟着它给定的字符串走把字典树建出来,求出fail指针,我们考虑两个字符串 A和B,
如果想要求B中有多少A的子串,转换一下就是有多少个B的前缀的后缀包含A,这个在AC自动机
的状态图中很容易表示,就是字符串B所占的结点中 有多少个结点顺着fail能到达A的尾结点,
并且fail构建出来的图是一棵树,转换成A的尾结点的子树中有多少个B的节点,用dfs序构建树状
数组能很容易完成,又因为有m组询问,我们把询问离线排序,就能解决问题啦。
#include<bits/stdc++.h>
#define LL long long
#define ll long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg using namespace std; const int N = 2e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = ; int n, m, pos, ans[N], t[N];
char s[N]; struct Qus {
int x, y, id;
bool operator < (const Qus &rhs) const {
return y < rhs.y;
}
} qus[N]; struct BIT {
int a[N];
void modify(int x, int v) {
for(int i = x; i < N; i += i & -i)
a[i] += v;
}
int sum(int x) {
int ans = ;
for(int i = x; i; i -= i & -i)
ans += a[i];
return ans;
}
} bit; struct Ac {
int ch[N][], val[N], dp[N], f[N], L[N], R[N], tot, sz, cnt, all;
bool vis[N];
vector<PII> vec[N];
vector<int> edge[N]; Ac(int sz) {this->sz = sz;}
void init() {tot = ;}
int newNode() {
tot++; f[tot] = ; val[tot] = ;
memset(ch[tot], , sizeof(ch[tot]));
return tot;
}
inline int idx(char c) {return c - 'a';}
void addStr(char *s) {
stack<int> stk;
int u = ;
stk.push();
for(int i = ; s[i]; i++) {
if(s[i] == 'P') {
cnt++; val[u]++; t[cnt] = u;
while(pos <= n && qus[pos].y <= cnt)
vec[u].push_back(mk(qus[pos].x, qus[pos].id)), pos++;
} else if(s[i] == 'B') {
if(stk.size() > ) {
stk.pop();
u = stk.top();
}
} else {
int c = idx(s[i]);
if(!ch[u][c]) ch[u][c] = newNode();
u = ch[u][c];
stk.push(u);
}
}
} void build() {
queue<int> que;
for(int c = ; c < sz; c++) {
int v = ch[][c];
if(!v) ch[][c] = ;
else f[v] = , que.push(v);
}
while(!que.empty()) {
int u = que.front(); que.pop();
val[u] |= val[f[u]];
for(int c = ; c < sz; c++) {
int v = ch[u][c];
if(!v) ch[u][c] = ch[f[u]][c];
else f[v] = ch[f[u]][c], que.push(v);
}
}
} void dfs(int u) {
L[u] = ++all;
for(int i = ; i < edge[u].size(); i++) {
int v = edge[u][i];
dfs(v);
}
R[u] = all;
} void solve(char *s) {
for(int i = ; i <= tot; i++)
edge[f[i]].push_back(i); dfs(); stack<int> stk;
int u = ;
stk.push();
bit.modify(L[], );
for(int i = ; s[i]; i++) {
if(s[i] == 'P') {
if(vis[u]) continue;
vis[u] = true; for(int i = ; i < vec[u].size(); i++) {
int x = t[vec[u][i].fi], id = vec[u][i].se;
ans[id] = bit.sum(R[x]) - bit.sum(L[x] - );
}
} else if(s[i] == 'B') {
if(stk.size() > ) {
bit.modify(L[u], -);
stk.pop();
u = stk.top();
}
} else {
int c = idx(s[i]);
u = ch[u][c];
stk.push(u);
bit.modify(L[u], );
}
}
for(int i = ; i <= n; i++) printf("%d\n", ans[i]);
}
} ac(); int main() {
ac.init(); pos = ;
scanf("%s%d", s, &n);
for(int i = ; i <= n; i++) {
scanf("%d%d", &qus[i].x, &qus[i].y);
qus[i].id = i;
}
sort(qus + , qus + + n);
ac.addStr(s);
ac.build();
ac.solve(s);
return ;
} /*
*/
bzoj 2434 AC自动机 + fail指针建树 + 树状数组的更多相关文章
- bzoj 2434 AC自动机+树状数组
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 3493 Solved: 1909[Submit][Sta ...
- 【BZOJ】1818: [Cqoi2010]内部白点(树状数组+离散+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1818 这一题一开始我就看错了,bzoj的那个绝对值109简直坑人,应该是10^9,我直接写了个暴力. ...
- bzoj 1818 [CQOI 2010] 内部白点 - 扫描线 - 树状数组
题目传送门 快速的列车 慢速的列车 题目大意 一个无限大的方格图内有$n$个黑点.问有多少个位置上下左右至少有一个黑点或本来是黑点. 扫描线是显然的. 考虑一下横着的线段,取它两个端点,横坐标小的地方 ...
- BZOJ 3236 AHOI 2013 作业 莫队+树状数组
BZOJ 3236 AHOI 2013 作业 内存限制:512 MiB 时间限制:10000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目大意: 此时己是凌晨两点,刚刚做了Co ...
- BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2221 Solved: 1179[Submit][Sta ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- 【BZOJ】1012: [JSOI2008]最大数maxnumber(树状数组+rmq)
http://www.lydsy.com/JudgeOnline/problem.php?id=1012 树状数组原来我只懂得sum和add的操作,今天才知道可以有求区间最值的操作,我学习了一下写了个 ...
- 【BZOJ 3295】动态逆序对 - 分块+树状数组
题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...
- BZOJ 1878: [SDOI2009]HH的项链 离线树状数组
1878: [SDOI2009]HH的项链 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
随机推荐
- zoj 2369 Two Cylinders
zoj 2369 Two Cylinders 链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2369 题意:已知两个无 ...
- 利用枚举算法实现todoList:把对应项添加的内容列表
功能: 点击城市列表项,如果内容列表不存在,则插入点击项: 如果内容列表中已存在,则不插入,然后把内容列表中的对应项放到第一位. HTML代码: <!DOCTYPE html> <h ...
- IntelliJ IDEA 热加载
修改java文件后 win按:Ctrl+Shift+F9 mac按:cmd+Shift+F9 tomcat-maven-plugin 启动的项目也用这个快捷键热加载
- Java中哈希表(Hashtable)是如何实现的
Java中哈希表(Hashtable)是如何实现的 Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例.假设我们保存下面一组数据,第一列 ...
- loj515 「LibreOJ β Round #2」贪心只能过样例
传送门:https://loj.ac/problem/515 [题解] 容易发现S最大到1000000. 于是我们有一个$O(n^2*S)$的dp做法. 容易发现可以被bitset优化. 于是复杂度就 ...
- bzoj 1635: [Usaco2007 Jan]Tallest Cow 最高的牛——差分
Description FJ's N (1 <= N <= 10,000) cows conveniently indexed 1..N are standing in a line. E ...
- Spring4+SpringMVC+MyBatis整合思路(山东数漫江湖)
1.Spring框架的搭建 这个很简单,只需要web容器中注册org.springframework.web.context.ContextLoaderListener,并指定spring加载配置文件 ...
- Winform Socket通信
Socket相关概念[端口] 在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应 ...
- 更改控件中DrawableLeft图片的大小,图片与文字的距离
Drawable drawable=getResources().getDrawable(R.drawable.xx); //获取图片 drawable.setBounds(left, top, ri ...
- 线程,JSP,Servlet面试题
线程编程方面 60.java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 答:有两种实现方法,分别是继承Thread类与实现Runna ...