1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| #include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define maxn 600005 #define put() putchar('\n') #define Tp template<typename T> #define Ts template<typename T,typename... Ar> using namespace std; Tp void read(T &x){ int f=1;x=0;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();} x*=f; } namespace Debug{ Tp void _debug(char* f,T t){cerr<<f<<'='<<t<<endl;} Ts void _debug(char* f,T x,Ar... y){while(*f!=',') cerr<<*f++;cerr<<'='<<x<<",";_debug(f+1,y...);} #define gdb(...) _debug((char*)#__VA_ARGS__,__VA_ARGS__) }using namespace Debug; #define fi first #define se second #define mk make_pair const int mod=1e9+7; int power(int x,int y=mod-2) { int sum=1; while (y) { if (y&1) sum=sum*x%mod; x=x*x%mod;y>>=1; } return sum; } int n; struct node { int l,r,root; }g[maxn]; int rnums; string ts[maxn]; struct yyy { int nex[26],vis[26],fail,val; }a[maxn]; int tot,cnt,w[maxn],stac[maxn]; int clone() { int now=0; if (tot) now=stac[tot--]; else now=++cnt; for (int i=0;i<26;i++) a[now].nex[i]=a[now].vis[i]=0; a[now].fail=a[now].val=0; return now; } void insert(int root,string s,int fl) { int now=root,len=s.size(),i; for (i=0;i<len;i++) { if (!a[now].nex[s[i]-'a']) a[now].nex[s[i]-'a']=clone(),a[now].vis[s[i]-'a']=1; now=a[now].nex[s[i]-'a']; } a[now].val+=fl; } void clear(int x) { stac[++tot]=x;int i; for (i=0;i<26;i++) if (a[x].vis[i]) { clear(a[x].nex[i]);a[x].nex[i]=0; } } queue<int>q; void build(int root) { int i,x; for (i=0;i<26;i++) if (a[root].nex[i]) a[a[root].nex[i]].fail=root,q.push(a[root].nex[i]); else a[root].nex[i]=root; while (!q.empty()) { x=q.front();q.pop();
a[x].val+=a[a[x].fail].val; for (i=0;i<26;i++) if (a[x].nex[i]) a[a[x].nex[i]].fail=a[a[x].fail].nex[i],q.push(a[x].nex[i]); else a[x].nex[i]=a[a[x].fail].nex[i]; } } int query(int root,string s) { int i,len=s.size(),x=root; ll ans=0; for (i=0;i<len;i++) { x=a[x].nex[s[i]-'a']; ans+=a[x].val;
} return ans; } signed main(void){ freopen("1.in","r",stdin); int i,j,op,T,times=0;string s; read(T); while (T--) { read(op);cin>>s; if (op<=2) { int fl=(op==1?1:-1); ++times;w[times]=fl;ts[times]=s; ++rnums;g[rnums].l=g[rnums].r=times,g[rnums].root=clone(); insert(g[rnums].root,ts[times],w[times]); build(g[rnums].root); for (i=rnums;i>=2;i--) if (g[i].r-g[i].l==g[i-1].r-g[i-1].l) { clear(g[i].root),clear(g[i-1].root); g[i-1].root=clone(); for (j=g[i-1].l;j<=g[i].r;j++) insert(g[i-1].root,ts[j],w[j]); build(g[i-1].root);g[i-1].r=g[i].r;
rnums--; } } else { ll ans=0; for (i=1;i<=rnums;i++) ans+=query(g[i].root,s); printf("%lld\n",ans); fflush(stdout); } } return 0; }
|