给定模式串 \(s\),\(q\) 次询问,求 \(t\) 在 \(s\) 中出现次数。
其中每个字符以正整数编码,强制在线。
后缀树 板子。没写过考场摸出来了,记录下代码。\(O(n\log n)\)。
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#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__)
using namespace std;
using namespace __gnu_pbds;
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cfast ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define ll long long
#define ull unsigned long long
#define intz(x,y) memset((x),(y),sizeof((x)))
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
#define tup(x) array<int,(x)>
inline ll read(){ll x=0,f=1;char ch=nc();while(ch<48||ch>57){if(ch=='-')f=-1;ch=nc();}while(ch>=48&&ch<=57)x=x*10+ch-48,ch=nc();return x*f;
}
//void write(int x){cout<<x<<' ';}
//void write(pii x){cout<<"P("<<x.fi<<','<<x.se<<")\n";}
//void write(vector<auto>x){for(auto i:x)write(i);cout<<'\n';}
//void write(auto *a,int l,int r){for(int i=l;i<=r;i++)write(a[i]);cout<<'\n';}
inline ll lowbit(ll x){return x&-x;}
inline int pcount(ll x){for(int i=0,res=0;;res+=(x>>i)&1,i++)if(i>60)return res;
}//struct mt{
// ll v;
// mt(){v=0;}
// mt(int x){this->v=x;}
// inline mt operator+(mt x){return {(v+x.v)%mod};}
// inline mt operator-(mt x){return {(v+mod-x.v)%mod};}
// inline mt operator*(mt x){return {1ll*v*x.v%mod};}
//};
//inline void add(mt &x,mt y){x=x+y;}
//mt qp(mt x,int y){mt res(1);for(;y;x=x*x,y>>=1)if(y&1)res=res*x;return res;}
const int N=2e5+5,M=1e6+5,p=13131;
vector<int>e[N];__gnu_pbds::gp_hash_table<int,int>son[N];
int s[N],id[N],rk[N],h[N],pos[N],n,q,op,z[N],tp,tot,f[N],T[N],siz[N],d[N];
ull hsh[N],pw[N],hs[N];
inline ull get(int l,int r){return hsh[r]-hsh[l-1]*pw[r-l+1];}
inline ull gett(int l,int r){return hs[r]-hs[l-1]*pw[r-l+1];}
int cnt[M],x[N],y[N];
void get(){int ct=1e6;for(int i=1;i<=n;i++)++cnt[x[i]=s[i]];for(int i=2;i<=ct;i++)cnt[i]+=cnt[i-1];for(int i=1;i<=n;i++)id[cnt[x[i]]--]=i;for(int k=1;k<=n;k<<=1){int t=0;for(int i=n-k+1;i<=n;i++)y[++t]=i;for(int i=1;i<=n;i++)if(id[i]>k)y[++t]=id[i]-k;memset(cnt,0,sizeof(cnt));for(int i=1;i<=n;i++)++cnt[x[i]];for(int i=2;i<=ct;i++)cnt[i]+=cnt[i-1];for(int i=n;i>=1;i--)id[cnt[x[y[i]]]--]=y[i],y[i]=0;swap(x,y);x[id[1]]=t=1;for(int i=2;i<=n;i++){if(y[id[i]]==y[id[i-1]]&&y[id[i]+k]==y[id[i-1]+k])x[id[i]]=t;else x[id[i]]=++t;}if(t==n)return;ct=t; }
}
void build(){vector<int>p;z[tp=1]=tot=n+1;d[n+1]=1;for(int i=1;i<=n;i++){while(tp&&pos[z[tp]]>h[i])--tp;if(pos[z[tp]]^h[i])++tot,f[z[tp+1]]=tot,son[tot][s[id[i-1]+h[i]]]=z[tp+1],f[tot]=z[tp],son[z[tp]][s[id[i-1]+pos[z[tp]]]]=tot,d[tot]=i,z[++tp]=tot,pos[tot]=h[i],p.pb(tot),f[i]=tot,son[tot][s[id[i]+h[i]]]=i;else f[i]=z[tp],son[z[tp]][s[id[i]+h[i]]]=i;z[++tp]=i,pos[i]=n-id[i]+1,p.pb(i),d[i]=i;}for(int i:p)e[f[i]].pb(i);
}
void dfs(int u){siz[u]=(u<=n);for(int v:e[u])dfs(v),siz[u]+=siz[v];
}
inline void UesugiErii(){cin>>op>>n>>q,pw[0]=1;for(int i=1;i<=1e5;i++)pw[i]=pw[i-1]*p;for(int i=1;i<=n;i++)cin>>s[i],hsh[i]=hsh[i-1]*p+s[i];s[n+1]=-1;for(int i=n+1;i<=n<<1;i++)hsh[i]=-1;get();for(int i=1;i<=n;i++)rk[id[i]]=i;for(int i=1,t=0;i<=n;i++){if(t)--t;while(s[i+t]==s[id[rk[i]-1]+t])++t;h[rk[i]]=t;}build();dfs(n+1);int lst=0;while(q--){int len;cin>>len;for(int i=1;i<=len;i++){cin>>T[i];if(op)T[i]^=lst;hs[i]=hs[i-1]*p+T[i];}int u=n+1,_=len,t=1,ans=0;while(t<=len){int p=T[t];if(son[u].find(p)!=son[u].end())break;int L=pos[son[u][p]]-pos[u];int v=son[u][p];if(L<_&&get(id[d[v]]+pos[u],id[d[v]]+pos[v]-1)==gett(len-_+1,len-_+L))_-=L,u=v,t+=L;else{if(gett(len-_+1,len)==get(id[d[v]]+pos[u],id[d[v]]+pos[u]+_-1))ans=siz[v];break;}}cout<<(lst=ans)<<'\n';}
}
signed main(){cfast;int _=1;//cin>>_;for(;_;_--)UesugiErii();return 0;
}