CF710F String Set Queries

这个询问就是 ACAM。

添加操作,考虑二进制分组,重构 ACAM 能做到 \(O(\sum|S|\log \sum|S|)\)

删除操作,考虑给字符串赋权,删除操作就加一个权为 \(-1\) 的字符串即可。

询问对每个 ACAM 都跑一遍,最多跑 \(\log\sum|S|\) 次。则总复杂度仍是单 \(\log\)

Takanashi Rikka
// Problem: CF710F String Set Queries
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF710F
// Memory Limit: 750 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define fin(x) freopen(#x".in","r",stdin)
#define fout(x) freopen(#x".out","w",stdout)
#define fr(x) fin(x),fout(x);
#define Fr(x,y) fin(x),fout(y)
#define INPUT(_1,_2,FILE,...) FILE
#define IO(...) INPUT(__VA_ARGS__,Fr,fr)(__VA_ARGS__)
#define pb push_back
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define intz(x,z) memset((x),(z),sizeof((x)))
#define cfast ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
inline ll lowbit(ll x){return x&-x;}
#define fi first
#define se second
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
inline void cmx(auto &x,ll y){if(y>x)x=y;}
inline void cmn(auto &x,ll y){if(y<x)x=y;}
const int N=3e5+5;
struct ACAM{
	vector<int>t[26],lst,f,val;int sz,tot;
	vector<vector<int> >e;
	void init(int siz){
		for(int i=0;i<26;i++)
			t[i].clear(),t[i].resize(siz+5);
		lst.clear(),f.clear(),val.clear(),e.clear();
		lst.resize(siz+5),f.resize(siz+5),val.resize(siz+5);
		e.resize(siz+5),tot=1;
	}
	int add(string s){
		int u=1;
		for(int i=0,p;i<s.size();u=t[p][u],i++)
			if(!t[p=s[i]-'a'][u])t[p][u]=++tot,lst[tot]=u;
		return u;
	}
	void dfs(int u,int fa){
		for(int v:e[u])
			val[v]+=val[u],dfs(v,u);
	}
	void build(){
		queue<int>dl;
		for(int i=0;i<26;i++)
			(t[i][1]?(dl.push(t[i][1]),f[t[i][1]]):t[i][1])=1;
		while(!dl.empty()){
			int u=dl.front();dl.pop();
			for(int i=0;i<26;i++)
				(t[i][u]?(dl.push(t[i][u]),f[t[i][u]]):t[i][u])=t[i][f[u]];
		}
		for(int i=2;i<=tot;i++)
			e[f[i]].pb(i);
		dfs(1,0);
	}
	int query(string T){
		int res=0,u=1;
		for(int i=0,p;i<T.size();i++)
			u=(!t[p=T[i]-'a'][u]?t[p][f[u]]:t[p][u]),res+=val[u];
		return res;
	}
};ACAM w[30];
string s[N];
int v[N],tot,ed[N],tp,sum[N];
void UesugiErii(){
	int _;cin>>_;
	while(_--){
		int op,sz;cin>>op;
		if(op<=2){
			++tot,cin>>s[tot],v[tot]=(op==1?1:-1),sz=1;
			sum[tot]=sum[tot-1]+s[tot].size();
			while(tp&&w[tp].sz==sz)--tp,sz*=2;
			w[++tp].init(sum[tot]-sum[tot-sz]);w[tp].sz=sz;
			for(int i=tot-sz+1;i<=tot;i++)
				ed[i]=w[tp].add(s[i]),w[tp].val[ed[i]]+=v[i];
			w[tp].build();
		}else{
			string t;int ans=0;cin>>t;
			for(int i=1;i<=tp;i++)
				ans+=w[i].query(t);
			cout<<ans<<'\n';
		}
	}
}
signed main(){
	//cfast;
	int _=1;//cin>>_;
	for(;_;_--)UesugiErii();
	return 0;
}

posted @ 2025-12-17 19:27  Uesugi1  阅读(7)  评论(0)    收藏  举报