# 思路

else trie[now][i]=trie[fail[now]][i];


void dfs(int x){
//printf("==%d\n",x);
for(int i = 0; i < (int)Q[x].size(); i++){
int y = Q[x][i].fst;
ans[Q[x][i].sc]=sum(ed[y])-sum(bg[y]-1);
}
for(int i = 0; i < 26; i++){
int y = ac.trie[x][i];
if(!y||h[y]<=h[x])continue;
dfs(y);
}
}


# 代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>

#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 3e5+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);

vector<int>v[maxn];
int id[maxn];
struct AC{
//局部变量没有默认0!
int trie[maxn][26];
int num[maxn];//单词出现次数
int fail[maxn],fa[maxn];
int tot,rt;
int ntot;
//多测可写个init
void init(){tot=0;mem(vis,0);mem(trie,0);rt=0;ntot=0;}
if(c=='P'){
num[rt]++;
id[++ntot]=rt;
return;
}
if(c=='B'){
rt=fa[rt];
return;
}
int x = c-'a';
if(!trie[rt][x]){
trie[rt][x]=++tot;
fa[tot]=rt;
}
//fa[trie[rt][x]]=rt;
rt=trie[rt][x];
}
void build(){
queue<int>q;
for(int i = 0; i < 26; i++){
if(trie[0][i]){
//fail[trie[0][i]]=0;
//v[0].pb(trie[0][i]);
q.push(trie[0][i]);
}
}
while(!q.empty()){
int now = q.front();
q.pop();
for(int i = 0; i < 26; i++){
////让这个节点的失败指针指向(((他父亲节点)的失败指针所指向的那个节点)的下一个相同节点)
if(trie[now][i]){
fail[trie[now][i]]=trie[fail[now]][i];
//v[trie[fail[now]][i]].pb(trie[now][i]);
q.push(trie[now][i]);
}
else trie[now][i]=trie[fail[now]][i];
//否则就让当前节点的这个子节点指向当前节点fail指针的这个子节点
}
v[fail[now]].pb(now);
}
}

}ac;
char a[maxn];
int bg[maxn],ed[maxn];
int S[maxn],tot;
void gao(int x){
S[++tot]=x;
bg[x]=tot;
for(int i = 0; i < (int)v[x].size(); i++){
int y =v[x][i];
gao(y);
}
//S[++tot]=x;
ed[x]=tot;
}
int tree[maxn];
int lowbit(int x){return x&-x;}
for(int i = x; i <= tot; i+=lowbit(i)){tree[i]+=c;}
}
int sum(int x){
int ans =0;
for(int i = x; i; i-=lowbit(i))ans+=tree[i];
return ans;
}
vector<PI>Q[maxn];
int ans[maxn];
/*
void dfs(int x){
//printf("%d\n",x);
for(int i = 0; i < (int)Q[x].size(); i++){
int y = Q[x][i].fst;
ans[Q[x][i].sc]=sum(ed[y])-sum(bg[y]-1);
}
for(int i = 0; i < 26; i++){
int y = ac.trie[x][i];
if(!y||(y==ac.trie[ac.fail[x]][i]))continue;
dfs(y);
}
}*/
void sv(){
int now = 0;
int n = strlen(a+1);
int world=0;
for(int i = 1; i <= n; i++){
if(a[i]=='B'){
now=ac.fa[now];
continue;
}
else if(a[i]=='P'){
world++;
for(int j = 0; j < (int)Q[now].size(); j++){
int x = Q[now][j].fst;
int y = Q[now][j]. sc;
ans[y]=sum(ed[x])-sum(bg[x]-1);
}
continue;
}
else{
int x=a[i]-'a';
now=ac.trie[now][x];
}
}
}
int main(){
ac.init();
tot=0;
scanf("%s", a+1);
int n = strlen(a+1);
for(int i = 1; i <= n; i++){
}
ac.build();
int m;
scanf("%d", &m);
for(int i = 1; i <= m; i++){
int x,y;
scanf("%d %d", &x, &y);
x=id[x];y=id[y];
Q[y].pb(make_pair(x,i));
}
gao(0);
//dfs(0);
sv();
for(int i = 1; i <= m; i++){
printf("%d\n",ans[i]);
}
return 0;
}
/*
aPaPBbP
3
1 2
1 3
2 3

a
aa
aa
*/


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>

#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 3e5+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);

vector<int>v[maxn];
int id[maxn];
int h[maxn];
struct AC{
//局部变量没有默认0!
int trie[maxn][26];
int num[maxn];//单词出现次数
int fail[maxn],fa[maxn];
int tot,rt;
int ntot;
int H;
//多测可写个init
void init(){tot=0;mem(vis,0);mem(trie,0);rt=0;ntot=0;H=0;}
if(c=='P'){
num[rt]++;
id[++ntot]=rt;
return;
}
if(c=='B'){
rt=fa[rt];H--;
return;
}
int x = c-'a';
if(!trie[rt][x]){
trie[rt][x]=++tot;
fa[tot]=rt;
}
//fa[trie[rt][x]]=rt;
rt=trie[rt][x];
h[rt]=++H;
}
void build(){
queue<int>q;
for(int i = 0; i < 26; i++){
if(trie[0][i]){
fail[trie[0][i]]=0;
//v[0].pb(trie[0][i]);
q.push(trie[0][i]);
}
}
while(!q.empty()){
int now = q.front();
q.pop();
for(int i = 0; i < 26; i++){
////让这个节点的失败指针指向(((他父亲节点)的失败指针所指向的那个节点)的下一个相同节点)
if(trie[now][i]){
fail[trie[now][i]]=trie[fail[now]][i];
//v[trie[fail[now]][i]].pb(trie[now][i]);
q.push(trie[now][i]);
}
else trie[now][i]=trie[fail[now]][i];
//否则就让当前节点的这个子节点指向当前节点fail指针的这个子节点
}
v[fail[now]].pb(now);
}
}

}ac;
char a[maxn];
int bg[maxn],ed[maxn];
int S[maxn],tot;
void gao(int x){
S[++tot]=x;
bg[x]=tot;
for(int i = 0; i < (int)v[x].size(); i++){
int y =v[x][i];
gao(y);
}
//S[++tot]=x;
ed[x]=tot;
}
int tree[maxn];
int lowbit(int x){return x&-x;}
for(int i = x; i <= tot; i+=lowbit(i)){tree[i]+=c;}
}
int sum(int x){
int ans =0;
for(int i = x; i; i-=lowbit(i))ans+=tree[i];
return ans;
}
vector<PI>Q[maxn];
int ans[maxn];

void dfs(int x){
//printf("==%d\n",x);
for(int i = 0; i < (int)Q[x].size(); i++){
int y = Q[x][i].fst;
ans[Q[x][i].sc]=sum(ed[y])-sum(bg[y]-1);
}
for(int i = 0; i < 26; i++){
int y = ac.trie[x][i];
if(!y||h[y]<=h[x])continue;
dfs(y);
}
}
void sv(){
int now = 0;
int n = strlen(a+1);
int world=0;
for(int i = 1; i <= n; i++){
if(a[i]=='B'){
now=ac.fa[now];
continue;
}
else if(a[i]=='P'){
world++;
for(int j = 0; j < (int)Q[now].size(); j++){
int x = Q[now][j].fst;
int y = Q[now][j]. sc;
ans[y]=sum(ed[x])-sum(bg[x]-1);
}
continue;
}
else{
int x=a[i]-'a';
now=ac.trie[now][x];
}
}
}
int main(){
ac.init();
tot=0;
scanf("%s", a+1);
int n = strlen(a+1);
for(int i = 1; i <= n; i++){
}
ac.build();
int m;
scanf("%d", &m);
for(int i = 1; i <= m; i++){
int x,y;
scanf("%d %d", &x, &y);
x=id[x];y=id[y];
Q[y].pb(make_pair(x,i));
}
gao(0);
dfs(0);
//sv();
for(int i = 1; i <= m; i++){
printf("%d\n",ans[i]);
}
return 0;
}
/*
asPdPasPddPhBdPhPnaPasP
8
1 5
2 6
3 8
4 3
7 7
2 5
6 8
1 8

a
aa
aa
*/

posted @ 2019-09-27 13:41  wrjlinkkkkkk  阅读(123)  评论(0编辑  收藏  举报