全TLE版:
#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define rep(x,a,b) for(int x=(a);x<=(b);++x)
#define rop(x,a,b) for(int x=(a);x<(b);++x)
#define per(x,a,b) for(int x=(a);x>=(b);--x)
#define pb push_back
using namespace std;
const int N = 2e5 + 10;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
ll llread(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
int n, nt = 1, mapp[N], m;
int endd[N];
char ogn[N];
struct node{
int y, id;
};
vector<node> p[N];
struct Edge{//fail -> now
int to, nxt;
}e[N<<1];
int head[N], ecnt = 0, tot;
void addedge( int u , int v ){
e[++ecnt] = (Edge){v,head[u]};
head[u] = ecnt;
}
queue<int> q;
struct tree_node{
int son[26], fail, flag, fa;
};
struct Trie{
tree_node t[N];
int insert( int now , char s ){
// cout << s << "\n";
int v = s - 'a';
if( !t[now].son[v] ){
// cout << now << " " << v << "\n";
t[now].son[v] = ++nt;
t[t[now].son[v]].fa = now;
}
return t[now].son[v];
}
int back( int now ){return t[now].fa;}
void ed( int now ){t[now].flag = ++tot;endd[tot] = now;}
void get_fail(){
for( int i = 0 ; i < 26 ; ++i )t[0].son[i] = 1;
q.push(1);t[1].fail = 0;
while( !q.empty() ){
int now = q.front();q.pop();
int fafail = t[now].fail;
for( int i = 0 ; i < 26 ; ++i ){
int v = t[now].son[i];
if(!v){t[now].son[i] = t[fafail].son[i];continue;}
t[v].fail = t[fafail].son[i];
q.push(v);
}
}
}
}AC;
struct BIT{
int c[N];
int lowbit( int x ){
return x & -x;
}
void update( int x , int w ){
while( x <= nt ){
x += lowbit(x);
c[x] += w;
}
}
int query( int x ){int res = 0;while(x > 0){res += c[x];x -= lowbit(x);};}
}bit;
int dn, dfn[N], vis[N], sz[N];
int ans[N];
void dfsfail( int x ){
dfn[x] = ++dn;vis[x] = 1;sz[x] = 1;
for( int i = head[x] ; i ; i = e[i].nxt ){
int v = e[i].to;
if( !vis[v] ){
dfsfail(v);
sz[x] += sz[v];
}
}
return ;
}
void dfstrie( int x ){
bit.update(dfn[x],1);
if( AC.t[x].flag != 0 ){
int it = AC.t[x].flag;
for( int i = 0 ; i < p[it].size() ; ++i ){
int f = p[it][i].y , id = p[it][i].id;
ans[id] = bit.query(dfn[f] + sz[f] - 1) - bit.query(dfn[f] - 1);
}
}
for( int i = 0 ; i < 26 ; ++i )
if( AC.t[x].son[i] > 0 )dfstrie(AC.t[x].son[i]);
bit.update(dfn[x],-1);
return ;
}
int main(){
cin >> (ogn+1);
n = strlen(ogn+1);
for( int i = 1, now = 1 ; i <= n ; ++i ){
if( ogn[i] == 'B' ){now = AC.back(now);}
else if( ogn[i] == 'P' ){AC.ed(now);}
else now = AC.insert(now,ogn[i]);
// cout << i << " " << now << "\n";
}
m = read();
for( int i = 1, x, y ; i <= m ; ++i ){
x = read();y = read();
p[y].pb((node){x,i});
}
for( int i = 2 ; i <= nt ; ++i )addedge(AC.t[i].fail,i);
dfsfail(1);
dfstrie(1);
for( int i = 1 ; i <= m ; ++i )cout << ans[i] << "\n";
return 0;
}
全WA版:
#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define rep(x,a,b) for(int x=(a);x<=(b);++x)
#define rop(x,a,b) for(int x=(a);x<(b);++x)
#define per(x,a,b) for(int x=(a);x>=(b);--x)
#define pb push_back
using namespace std;
const int N = 2e5 + 10;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
ll llread(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
int n, nt = 1, mapp[N], m;
int endd[N];
char ogn[N];
struct node{
int y, id;
};
vector<node> p[N];
struct Edge{//fail -> now
int to, nxt;
}e[N<<1];
int head[N], ecnt = 0, tot;
void addedge( int u , int v ){
e[++ecnt] = (Edge){v,head[u]};
head[u] = ecnt;
}
queue<int> q;
struct tree_node{
int son[26], fail, flag, fa;
};
struct Trie{
tree_node t[N];
int insert( int now , char s ){
// cout << s << "\n";
int v = s - 'a';
if( !t[now].son[v] ){
// cout << now << " " << v << "\n";
t[now].son[v] = ++nt;
t[t[now].son[v]].fa = now;
}
return t[now].son[v];
}
int back( int now ){return t[now].fa;}
void ed( int now ){t[now].flag = ++tot;endd[tot] = now;}
void get_fail(){
for( int i = 0 ; i < 26 ; ++i )t[0].son[i] = 1;
q.push(1);t[1].fail = 0;
while( !q.empty() ){
int now = q.front();q.pop();
int fafail = t[now].fail;
for( int i = 0 ; i < 26 ; ++i ){
int v = t[now].son[i];
if(!v){t[now].son[i] = t[fafail].son[i];continue;}
t[v].fail = t[fafail].son[i];
q.push(v);
}
}
}
}AC;
struct BIT{
int c[N];
int lowbit( int x ){
return x & -x;
}
void update( int x , int w ){
while( x <= nt ){
x += lowbit(x);
c[x] += w;
if( x == 0 )return ;
}
}
int query( int x ){int res = 0;while(x > 0){res += c[x];x -= lowbit(x);};}
}bit;
int dn, dfn[N], vis[N], sz[N];
int ans[N];
void dfsfail( int x ){
dfn[x] = ++dn;vis[x] = 1;sz[x] = 1;
for( int i = head[x] ; i ; i = e[i].nxt ){
int v = e[i].to;
if( !vis[v] ){
dfsfail(v);
sz[x] += sz[v];
}
}
return ;
}
void dfstrie( int x ){
bit.update(dfn[x],1);
if( AC.t[x].flag != 0 ){
int it = AC.t[x].flag;
for( int i = 0 ; i < p[it].size() ; ++i ){
int f = p[it][i].y , id = p[it][i].id;
ans[id] = bit.query(dfn[f] + sz[f] - 1) - bit.query(dfn[f] - 1);
}
}
for( int i = 0 ; i < 26 ; ++i )
if( AC.t[x].son[i] > 0 )dfstrie(AC.t[x].son[i]);
bit.update(dfn[x],-1);
return ;
}
int main(){
cin >> (ogn+1);
n = strlen(ogn+1);
for( int i = 1, now = 1 ; i <= n ; ++i ){
if( ogn[i] == 'B' ){now = AC.back(now);}
else if( ogn[i] == 'P' ){AC.ed(now);}
else now = AC.insert(now,ogn[i]);
// cout << i << " " << now << "\n";
}
m = read();
for( int i = 1, x, y ; i <= m ; ++i ){
x = read();y = read();
p[y].pb((node){x,i});
}
for( int i = 2 ; i <= nt ; ++i )addedge(AC.t[i].fail,i);
dfsfail(1);
dfstrie(1);
for( int i = 1 ; i <= m ; ++i )cout << ans[i] << "\n";
return 0;
}
不懂就问:这两种树状数组的写法为啥一个死循环,一个就能跑呢?