求助,线段树合并做法卡空间卡到哭
查看原帖
求助,线段树合并做法卡空间卡到哭
131591
蒟蒻君HJT泽渡透香楼主2022/5/7 20:01
#include <bits/stdc++.h>
using namespace std;
const int N=4e6+5,M=3.2e7+5;
int tr[N][26];
int n,q,fail[N],tot=0,R=0,root[N];
int sum=0,ls[M],rs[M],val[M],ed[100005],Ans[100005];
vector<int>vec[N],vt[N],g[N];
char s[N/2];
void insert(int id){
	int now=0,r=0,l=strlen(s),u;
	while(r<l){
		u=(int)(s[r]-'a');
		if(!tr[now][u]) tr[now][u]=++tot;
		now=tr[now][u],++r;
		if(id>0) vec[now].push_back(id);
	}
	if(id<0) ed[-id]=now;
	return ;
}
void build(){
	queue<int>q;
	for(int i=0;i<26;++i) if(tr[0][i]) q.push(tr[0][i]);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;++i){
			if(tr[u][i]) fail[tr[u][i]]=tr[fail[u]][i],q.push(tr[u][i]);
			else tr[u][i]=tr[fail[u]][i];
		}
	}
	return ;
}
int modify(int x,int l,int r,int y){
	if(!x) x=++sum;
	if(l==r){val[x]=1;return x;}
	int mid=l+r>>1;
	if(y<=mid) ls[x]=modify(ls[x],l,mid,y);
	else rs[x]=modify(rs[x],mid+1,r,y);
	val[x]=val[ls[x]]+val[rs[x]];
	return x;
}
int merge(int x,int y,int l,int r){
	if(!x || !y) return x|y;
	if(l==r){val[x]=val[x]|val[y];return x;}
	int mid=l+r>>1;
	ls[x]=merge(ls[x],ls[y],l,mid);
	rs[x]=merge(rs[x],rs[y],mid+1,r);
	val[x]=val[ls[x]]+val[rs[x]];
	return x;
}
int ask(int x,int l,int r,int L,int R){
	if(L>R || !x) return 0;
	if(l==L && r==R) return val[x];
	int mid=l+r>>1;
	if(R<=mid) return ask(ls[x],l,mid,L,R);
	else if(L>=mid+1) return ask(rs[x],mid+1,r,L,R);
	return ask(ls[x],l,mid,L,mid)+ask(rs[x],mid+1,r,mid+1,R);
}
int q2[100005];
void dfs(int x){
	int si=vt[x].size(),sj=vec[x].size();
	for(int i=0;i<sj;++i) root[x]=modify(root[x],1,R,vec[x][i]);
	for(int i=0;i<si;++i) 
		dfs(vt[x][i]),root[x]=merge(root[x],root[vt[x][i]],1,R);
	int sk=g[x].size();
	for(int i=0;i<sk;++i) Ans[g[x][i]]=ask(root[x],1,R,1,q2[g[x][i]]);
	return ;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%s",s),insert(-i);
	scanf("%d",&q);
	int x,y;
	for(int i=1;i<=q;++i){
		scanf("%d",&x);
		if(x==1) scanf("%s",s),++R,insert(R);
		else scanf("%d",&y),q2[i-R]=R,g[ed[y]].push_back(i-R);
	}
	build();
	for(int i=1;i<=tot;++i) vt[fail[i]].push_back(i);
	dfs(0);
	for(int i=1;i<=q-R;++i) printf("%d\n",Ans[i]);
	return 0;
}
2022/5/7 20:01
加载中...