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;
}

浙公网安备 33010602011771号