题目分析:

画一下fail树,就会发现就是x的子树中属于y路径的,把y剖分一下,用线段树处理

$O(n*log^2 n)$。

代码:

 #include<bits/stdc++.h>
using namespace std; const int maxn = ; string str;
struct node{int ch[],fail,fa;}T[maxn];
int star[maxn],ans[maxn],num = ,snum,m;
int dfsin[maxn],dfsout[maxn],poss[maxn]; // failtree
int Tnb[maxn],top[maxn],sz[maxn];
vector <int> g[maxn];
vector<pair<int,int> > Qy[maxn]; void read(){
ios::sync_with_stdio(false);
cin.tie();
cin >> str;
int now = ;
for(int i=;i<str.length();i++){
if(str[i] == 'B') now = T[now].fa;
else if(str[i] == 'P') star[++snum] = now;
else{
if(T[now].ch[str[i]-'a']) now = T[now].ch[str[i]-'a'];
else{
T[now].ch[str[i]-'a'] = ++num;
T[num].fa = now;
now = num;
}
}
}
snum = ;
} void dfs(int now){
dfsin[now] = dfsout[now] = ++snum;
poss[snum] = now;
for(int i=;i<g[now].size();i++){
dfs(g[now][i]);
dfsout[now] = dfsout[g[now][i]];
}
} queue<int> q;
void BuildACAutomaton(){
q.push();T[].fail = ;
while(!q.empty()){
int k = q.front();q.pop();
for(int i=;i<;i++){
if(T[k].ch[i] == ) continue;
int ff = T[k].fail;
while(ff != && T[ff].ch[i] == ) ff = T[ff].fail;
if(T[ff].ch[i]==T[k].ch[i]||T[ff].ch[i]==)T[T[k].ch[i]].fail=;
else T[T[k].ch[i]].fail = T[ff].ch[i];
q.push(T[k].ch[i]);
g[T[T[k].ch[i]].fail].push_back(T[k].ch[i]);
}
}
snum = ; dfs(); snum = ;
} int QT[maxn*]; void Add(int now,int tl,int tr,int pos){
if(tl == tr){QT[now]++;return;}
int mid = (tl+tr)/;QT[now]++;
if(mid >= pos) Add(now<<,tl,mid,pos);
else Add(now<<|,mid+,tr,pos);
}
int Query(int now,int tl,int tr,int l,int r){
if(tl >= l && tr <= r) return QT[now];
if(tl > r || tr < l) return ;
int mid = (tl+tr)/;
return Query(now<<,tl,mid,l,r)+Query(now<<|,mid+,tr,l,r);
} void dfsmiao(int now){
for(int i=;i<;i++){
if(T[now].ch[i]==)continue;
dfsmiao(T[now].ch[i]);
sz[now] += sz[T[now].ch[i]];
}
sz[now]++;
} void dfsyeah(int now,int tp){
int son = ;top[now] = tp;Tnb[now] = ++snum;
for(int i=;i<;i++){
if(sz[T[now].ch[i]] > sz[son]) son = T[now].ch[i];
}
if(son) dfsyeah(son,tp);
for(int i=;i<;i++){
if(T[now].ch[i] == || T[now].ch[i] == son) continue;
dfsyeah(T[now].ch[i],T[now].ch[i]);
}
} void treechain(){
dfsmiao();
dfsyeah(,);
} void readquery(){
cin >> m;
for(int i=;i<=m;i++){
int x,y; cin >> x >> y;
x = star[x];y = star[y];
Qy[poss[dfsin[x]-]].push_back(make_pair(y,i));
Qy[poss[dfsout[x]]].push_back(make_pair(y,i));
}
} void solve(int endpos,int now){
if(ans[now]) ans[now] = -ans[now];
while(endpos){
ans[now] += Query(,,num,Tnb[top[endpos]],Tnb[endpos]);
endpos = T[top[endpos]].fa;
}
} void work(){
for(int i=;i<=num;i++){
int now = poss[i];
Add(,,num,Tnb[now]);
for(int j=;j<Qy[now].size();j++){
solve(Qy[now][j].first,Qy[now][j].second);
}
}
for(int i=;i<=m;i++) cout<<ans[i]<<endl;
} int main(){
//freopen("7.in","r",stdin);
read();
treechain();
BuildACAutomaton();
readquery();
work();
return ;
}

BZOJ2434 [NOI2011] 阿狸的打字机 【树链剖分】【线段树】【fail树】【AC自动机】的更多相关文章

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  2. 【BZOJ-3589】动态树 树链剖分 + 线段树 + 线段覆盖(特殊的技巧)

    3589: 动态树 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 405  Solved: 137[Submit][Status][Discuss] ...

  3. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  4. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  5. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  6. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  7. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  8. GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树

    GSS7Can you answer these queries VII 给出一棵树,树的节点有权值,有两种操作: 1.询问节点x,y的路径上最大子段和,可以为空 2.把节点x,y的路径上所有节点的权 ...

  9. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  10. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

随机推荐

  1. 【C#复习总结】细说表达式树

    1 前言 系类1:细说委托 系类2:细说匿名方法 系列3:细说Lambda表达式 系列4:细说泛型委托 系列5:细说表达式树 系列6:细说事件 涛声依旧,再续前言,接着用大佬的文章作为开头. 表达式树 ...

  2. 爬虫(三)之scrapy核心组件

    01-核心组件 ·五大核心组件的工作流程: 引擎(Scrapy) 用来处理整个系统的数据流处理, 触发事务(框架核心) 调度器(Scheduler) 用来接受引擎发过来的请求, 压入队列中, 并在引擎 ...

  3. Python _内置函数3_45

    reversed: #reversed() l = [1,2,3,4,5] l.reverse() print(l) #改变了原来的列表 l = [1,2,3,4,5] l2 = reversed(l ...

  4. H5 31-CSS元素显示模式转换

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. adb命令集合

    1. 获取序列号: adb get-serialno 2. 查看连接计算机的设备: adb devices 3. 重启机器: adb reboot 4. 重启到bootloader,即刷机模式: ad ...

  6. Comet OJ 热身赛(K题)principal(括号匹配问题+stack模拟)

    principal 已经提交 已经通过 23.66% Total Submission:131 Total Accepted:31 题目描述 阿尔比恩王国潜伏着代号白鸽队''的一群间谍.在没有任务的时 ...

  7. oc之证书

    https://www.cnblogs.com/MrJalen/p/6813309.html iOS推送证书生成pem文件(详细步骤)   1.pem文件概述 pem文件是服务器向苹果服务器做推送时候 ...

  8. Linux之磁盘挂载

    1.查看磁盘分区情况: fdisk -l 可以看到,红框中的硬盘没有分区. 2.开始分区: fdisk /dev/vdb 3.格式化分区: mkfs.xfs 分区名 4.挂载磁盘 挂载方式1: 手动挂 ...

  9. Zabbix appliance One Stop

    Download Zabbix appliancehttps://www.zabbix.com/download_appliance

  10. [转帖]SAP一句话入门:Sales and Distribution

    SAP一句话入门:Sales and Distribution http://blog.vsharing.com/MilesForce/A616565.html SD是Sales and Distri ...