Codeforces 1204G-インディーズアルバム

Codeforces 1204G-インディーズアルバム

問題の意味

N列、Iの文字列は、次の2つの方法で与えられます。
1、唯一の文字列Cが含まれている1、C、。
2,2 JCは、文字列が得られたJ cの文字列の最後に追加されます。
Mインタロゲーション時間、クエリは文字列sおよび整数xが与えられるたびに、Qは、最初の文字列をX、文字列sを数回起こります。

問題の解決策

文字列の数と右の位置ACオートマトンで来て、再び実行して+1の値の後に、文字列は、親配列に発生します。クエリ文字列メートルの場合は、ACオートマトンが失敗ツリーのプロパティを使用して、構築しますノードの右サブツリーが値に対応する文字列に失敗しています。
所見の文字列を与えられたN木である、木は、クエリ単語とフェンウィックツリーノードの重みを使用して、DFS、DFS配列では失敗することができます。

コード

#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
int n,m; 
int fa[N],ans[N];
char s[N],t[N];
int ver[N],head[N],nxt[N],tt;
int tr[N][26],fail[N],tot;
int dfn[N],id,Size[N];
int c[N];

vector<pair<int,int> > que[N];

void add(int u,int v){
	ver[++tt]=v;
	nxt[tt]=head[u];head[u]=tt;
}

int insert(char *s,int len){
	int u=0;
	for(int i=1;i<=len;i++){
		int ch=s[i]-'a';
		if(!tr[u][ch]) tr[u][ch]=++tot;
		u=tr[u][ch];
	}
	return u;
} 

queue<int> q;
vector<int> E[N];
void build(){
	for(int i=0;i<26;i++){
		if(tr[0][i]) q.push(tr[0][i]);
	}
	while(q.size()){
		int u=q.front();q.pop();
		E[fail[u]].push_back(u);
		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];
		}
	}
}

void AC_dfs(int u){
	int k=E[u].size();
	dfn[u]=++id;
	Size[u]=1;
	for(int i=0;i<k;i++){
		int v=E[u][i];
		AC_dfs(v);
		Size[u]+=Size[v];
	}
}

void update(int x,int y){
	for(;x<=id;x+=(x&-x)) c[x]+=y;
}

int query(int x){
	int ans=0;
	for(;x;x-=(x&-x)) ans+=c[x];
	return ans;
}

int solve(int x){
	return query(dfn[x]+Size[x]-1)-query(dfn[x]-1);
}

void dfs(int x,int u){
	int ch=s[x]-'a';
	u=tr[u][ch];
	update(dfn[u],1);
	for(int i=head[x];i;i=nxt[i]){
		int v=ver[i];
		dfs(v,u);
	}
	int k=que[x].size();
	for(int i=0;i<k;i++){
		ans[que[x][i].second]=solve(que[x][i].first);
	}
	update(dfn[u],-1);
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int op,x;
		scanf("%d",&op);
		if(op==2){
			scanf("%d",&x);
			fa[i]=x;
		}
		add(fa[i],i);
		scanf("%s",&s[i]);
	}
	scanf("%d",&m);
	for(int i=1;i<=m;i++){
		int idx;
		scanf("%d",&idx);
		scanf("%s",t+1);
		int len=strlen(t+1);
		int e=insert(t,len);
		que[idx].push_back(make_pair(e,i));
	}
	build();
	AC_dfs(0);
	for(int i=1;i<=n;i++){
		if(!fa[i]) dfs(i,0);
	}
	for(int i=1;i<=m;i++){
		printf("%d\n",ans[i]);
	}
	return 0;
}

おすすめ

転載: www.cnblogs.com/qjy73/p/12549046.html