纪念一次AC,水一篇blog
又是喜闻乐见的广义SAM题辣
题意:给一个trie,每次问询一个串在另一个串出现的次数
思路:建立广义SAM,离线所有询问,每次讲一个主串在fail树上的节点+1,处理询问就用fenwick维护子树和
这里注意,
1.广义SAM要用bfs建
2.每次从一个主串到下一个时,不要整个都减掉而是要在LCA处会和,这样复杂度就是对的
代码有点长但是很好打
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 200010
using namespace std;
struct fenwick{
int w[N],n,v;
inline void init(int c){ n=c; }
inline void add(int x){ for(;x<=n;x+=x&-x) ++w[x]; }
inline void dec(int x){ for(;x<=n;x+=x&-x) --w[x]; }
inline int sum(int x){ for(v=0;x;x&=x-1) v+=w[x]; return v; }
} w;
int h[N],cnt=1,d[N],l[N],r[N],clk,f[N];
int s[N][26],lst[N],v[N],n,m,tot=1,nc,q[N],A[N];
struct edge{ int v,nt; } G[N<<1];
namespace SAM{
int s[N][26],mx[N],f[N],cnt=1;
inline int extend(int p,int c){
int np=++cnt,q,nq;
mx[np]=mx[p]+1;
for(;p&&!s[p][c];p=f[p]) s[p][c]=np;
if(!p){ f[np]=1; return np; }
q=s[p][c];
if(mx[q]==mx[p]+1) f[np]=q;
else{
nq=++cnt;
mx[nq]=mx[p]+1;
f[nq]=f[q]; f[q]=f[np]=nq;
memcpy(s[nq],s[q],26<<2);
for(;p&&s[p][c]==q;p=f[p]) s[p][c]=nq;
}
return np;
}
inline void dfs(int x){
l[x]=++clk;
for(int i=h[x];i;i=G[i].nt) dfs(G[i].v);
r[x]=clk;
}
inline void buildTree(){
for(int i=2;i<=cnt;++i){
G[++::cnt]=(edge){i,h[f[i]]}; h[f[i]]=::cnt;
}
dfs(1);
}
}
char S[N],*T;
struct V{ int x,y,r; } g[N];
inline bool cv(V a,V b){ return a.y<b.y; }
inline void Btrie(int x){
if(!*T) return;
if(*T=='B'){ ++T; return; } else
if(*T=='P'){ v[++nc]=x; ++T; Btrie(x); }
else{
if(!s[x][*T-='a']) s[x][*T]=++tot;
f[tot]=x; d[tot]=d[x]+1; Btrie(s[x][*T++]); Btrie(x);
}
}
int main(){
scanf("%s%d",S,&m);
T=S; Btrie(1);
int l=1,r=0; lst[q[++r]=1]=1;
for(int x;l<=r;++l){
x=q[l];
for(int i=0;i<26;++i)
if(s[x][i]){
lst[s[x][i]]=SAM::extend(lst[x],i);
q[++r]=s[x][i];
}
}
SAM::buildTree(); w.init(SAM::cnt);
for(int i=1;i<=m;++i) scanf("%d%d",&g[i].x,&g[i].y),g[i].r=i;
sort(g+1,g+1+m,cv); v[0]=1;
for(int x,y=1,i=1,j=1;i<=m;){
while(j<=m && g[j].y==g[i].y) ++j;
x=v[g[i].y]; y=v[g[i-1].y];
while(d[x]>d[y]){
w.add(::l[lst[x]]); x=f[x];
}
while(d[y]>d[x]){
w.dec(::l[lst[y]]); y=f[y];
}
while(x!=y){
w.add(::l[lst[x]]); x=f[x];
w.dec(::l[lst[y]]); y=f[y];
}
for(;i<j;++i)
A[g[i].r]=w.sum(::r[lst[v[g[i].x]]])-w.sum(::l[lst[v[g[i].x]]]-1);
}
for(int i=1;i<=m;++i) printf("%d\n",A[i]);
}
放个LaTeXLaTeXLaTeX版本的代码恶心人~
#include<stdio.h>\#include<stdio.h>#include<stdio.h>
#include<string.h>\#include<string.h>#include<string.h>
#include<algorithm>\#include<algorithm>#include<algorithm>
#define N 200010\#define\ N\ 200010#define N 200010
using namespace std;using\ namespace\ std;using namespace std;
struct fenwick{struct\ fenwick\{struct fenwick{
int w[N],n,v;\quad int\ w[N],n,v;int w[N],n,v;
inline void init(int c){ n=c; }\quad inline\ void\ init(int\ c)\{\ n=c;\ \}inline void init(int c){ n=c; }
inline void add(int x){ for(;x<=n;x+=x&−x) ++w[x]; }\quad inline\ void\ add(int\ x)\{\ for(;x<=n;x+=x\&-x)\ ++w[x];\ \}inline void add(int x){ for(;x<=n;x+=x&−x) ++w[x]; }
inline void dec(int x){ for(;x<=n;x+=x&−x) −−w[x]; }\quad inline\ void\ dec(int\ x)\{\ for(;x<=n;x+=x\&-x)\ --w[x];\ \}inline void dec(int x){ for(;x<=n;x+=x&−x) −−w[x]; }
inline int sum(int x){ for(v=0;x;x&=x−1) v+=w[x]; return v; }\quad inline\ int\ sum(int\ x)\{\ for(v=0;x;x\&=x-1)\ v+=w[x];\ return\ v;\ \}inline int sum(int x){ for(v=0;x;x&=x−1) v+=w[x]; return v; }
} w;\}\ w;} w;
int h[N],cnt=1,d[N],l[N],r[N],clk,f[N];int\ h[N],cnt=1,d[N],l[N],r[N],clk,f[N];int h[N],cnt=1,d[N],l[N],r[N],clk,f[N];
int s[N][26],lst[N],v[N],n,m,tot=1,nc,q[N],A[N];int\ s[N][26],lst[N],v[N],n,m,tot=1,nc,q[N],A[N];int s[N][26],lst[N],v[N],n,m,tot=1,nc,q[N],A[N];
struct edge{ int v,nt; } G[N<<1];struct\ edge\{\ int\ v,nt;\ \}\ G[N<<1];struct edge{ int v,nt; } G[N<<1];
namespace SAM{namespace\ SAM\{namespace SAM{
int s[N][26],mx[N],f[N],cnt=1;\quad int\ s[N][26],mx[N],f[N],cnt=1;int s[N][26],mx[N],f[N],cnt=1;
inline int extend(int p,int c){\quad inline\ int\ extend(int\ p,int\ c)\{inline int extend(int p,int c){
int np=++cnt,q,nq;\quad \quad int\ np=++cnt,q,nq;int np=++cnt,q,nq;
mx[np]=mx[p]+1;\quad \quad mx[np]=mx[p]+1;mx[np]=mx[p]+1;
for(;p&&!s[p][c];p=f[p]) s[p][c]=np;\quad \quad for(;p\&\&!s[p][c];p=f[p])\ s[p][c]=np;for(;p&&!s[p][c];p=f[p]) s[p][c]=np;
if(!p){ f[np]=1; return np; }\quad \quad if(!p)\{\ f[np]=1;\ return\ np;\ \}if(!p){ f[np]=1; return np; }
q=s[p][c];\quad \quad q=s[p][c];q=s[p][c];
if(mx[q]==mx[p]+1) f[np]=q;\quad \quad if(mx[q]==mx[p]+1)\ f[np]=q;if(mx[q]==mx[p]+1) f[np]=q;
else{\quad \quad else\{else{
nq=++cnt;\quad \quad \quad nq=++cnt;nq=++cnt;
mx[nq]=mx[p]+1;\quad \quad \quad mx[nq]=mx[p]+1;mx[nq]=mx[p]+1;
f[nq]=f[q]; f[q]=f[np]=nq;\quad \quad \quad f[nq]=f[q];\ f[q]=f[np]=nq;f[nq]=f[q]; f[q]=f[np]=nq;
memcpy(s[nq],s[q],26<<2);\quad \quad \quad memcpy(s[nq],s[q],26<<2);memcpy(s[nq],s[q],26<<2);
for(;p&&s[p][c]==q;p=f[p]) s[p][c]=nq;\quad \quad \quad for(;p\&\&s[p][c]==q;p=f[p])\ s[p][c]=nq;for(;p&&s[p][c]==q;p=f[p]) s[p][c]=nq;
}\quad \quad \}}
return np;\quad \quad return\ np;return np;
}\quad \}}
inline void dfs(int x){\quad inline\ void\ dfs(int\ x)\{inline void dfs(int x){
l[x]=++clk;\quad \quad l[x]=++clk;l[x]=++clk;
for(int i=h[x];i;i=G[i].nt) dfs(G[i].v);\quad \quad for(int\ i=h[x];i;i=G[i].nt)\ dfs(G[i].v);for(int i=h[x];i;i=G[i].nt) dfs(G[i].v);
r[x]=clk;\quad \quad r[x]=clk;r[x]=clk;
}\quad \}}
inline void buildTree(){\quad inline\ void\ buildTree()\{inline void buildTree(){
for(int i=2;i<=cnt;++i){\quad \quad for(int\ i=2;i<=cnt;++i)\{for(int i=2;i<=cnt;++i){
G[++::cnt]=(edge){i,h[f[i]]}; h[f[i]]=::cnt;\quad \quad \quad G[++::cnt]=(edge)\{i,h[f[i]]\};\ h[f[i]]=::cnt;G[++::cnt]=(edge){i,h[f[i]]}; h[f[i]]=::cnt;
}\quad \quad \}}
dfs(1);\quad \quad dfs(1);dfs(1);
}\quad \}}
}\}}
char S[N],∗T;char\ S[N],*T;char S[N],∗T;
struct V{ int x,y,r; } g[N];struct\ V\{\ int\ x,y,r;\ \}\ g[N];struct V{ int x,y,r; } g[N];
inline bool cv(V a,V b){ return a.y<b.y; }inline\ bool\ cv(V\ a,V\ b)\{\ return\ a.y<b.y;\ \}inline bool cv(V a,V b){ return a.y<b.y; }
inline void Btrie(int x){inline\ void\ Btrie(int\ x)\{inline void Btrie(int x){
if(!∗T) return;\quad if(!*T)\ return;if(!∗T) return;
if(∗T==′B′){ ++T; return; } else\quad if(*T=='B')\{\ ++T;\ return;\ \}\ elseif(∗T==′B′){ ++T; return; } else
if(∗T==′P′){ v[++nc]=x; ++T; Btrie(x); }\quad if(*T=='P')\{\ v[++nc]=x;\ ++T;\ Btrie(x);\ \}if(∗T==′P′){ v[++nc]=x; ++T; Btrie(x); }
else{\quad else\{else{
if(!s[x][∗T−=′a′]) s[x][∗T]=++tot;\quad \quad if(!s[x][*T-='a'])\ s[x][*T]=++tot;if(!s[x][∗T−=′a′]) s[x][∗T]=++tot;
f[tot]=x; d[tot]=d[x]+1; Btrie(s[x][∗T++]); Btrie(x);\quad \quad f[tot]=x;\ d[tot]=d[x]+1;\ Btrie(s[x][*T++]);\ Btrie(x);f[tot]=x; d[tot]=d[x]+1; Btrie(s[x][∗T++]); Btrie(x);
}\quad \}}
}\}}
int main(){int\ main()\{int main(){
scanf("%s%d",S,&m);\quad scanf("\%s\%d",S,\&m);scanf("%s%d",S,&m);
T=S; Btrie(1);\quad T=S;\ Btrie(1);T=S; Btrie(1);
int l=1,r=0; lst[q[++r]=1]=1;\quad int\ l=1,r=0;\ lst[q[++r]=1]=1;int l=1,r=0; lst[q[++r]=1]=1;
for(int x;l<=r;++l){\quad for(int\ x;l<=r;++l)\{for(int x;l<=r;++l){
x=q[l];\quad \quad x=q[l];x=q[l];
for(int i=0;i<26;++i)\quad \quad for(int\ i=0;i<26;++i)for(int i=0;i<26;++i)
if(s[x][i]){\quad \quad \quad if(s[x][i])\{if(s[x][i]){
lst[s[x][i]]=SAM::extend(lst[x],i);\quad \quad \quad \quad lst[s[x][i]]=SAM::extend(lst[x],i);lst[s[x][i]]=SAM::extend(lst[x],i);
q[++r]=s[x][i];\quad \quad \quad \quad q[++r]=s[x][i];q[++r]=s[x][i];
}\quad \quad \quad \}}
}\quad \}}
SAM::buildTree(); w.init(SAM::cnt);\quad SAM::buildTree();\ w.init(SAM::cnt);SAM::buildTree(); w.init(SAM::cnt);
for(int i=1;i<=m;++i) scanf("%d%d",&g[i].x,&g[i].y),g[i].r=i;\quad for(int\ i=1;i<=m;++i)\ scanf("\%d\%d",\&g[i].x,\&g[i].y),g[i].r=i;for(int i=1;i<=m;++i) scanf("%d%d",&g[i].x,&g[i].y),g[i].r=i;
sort(g+1,g+1+m,cv); v[0]=1;\quad sort(g+1,g+1+m,cv);\ v[0]=1;sort(g+1,g+1+m,cv); v[0]=1;
for(int x,y=1,i=1,j=1;i<=m;){\quad for(int\ x,y=1,i=1,j=1;i<=m;)\{for(int x,y=1,i=1,j=1;i<=m;){
while(j<=m && g[j].y==g[i].y) ++j;\quad \quad while(j<=m\ \&\&\ g[j].y==g[i].y)\ ++j;while(j<=m && g[j].y==g[i].y) ++j;
x=v[g[i].y]; y=v[g[i−1].y];\quad \quad x=v[g[i].y];\ y=v[g[i-1].y];x=v[g[i].y]; y=v[g[i−1].y];
while(d[x]>d[y]){\quad \quad while(d[x]>d[y])\{while(d[x]>d[y]){
w.add(::l[lst[x]]); x=f[x];\quad \quad \quad w.add(::l[lst[x]]);\ x=f[x];w.add(::l[lst[x]]); x=f[x];
}\quad \quad \}}
while(d[y]>d[x]){\quad \quad while(d[y]>d[x])\{while(d[y]>d[x]){
w.dec(::l[lst[y]]); y=f[y];\quad \quad \quad w.dec(::l[lst[y]]);\ y=f[y];w.dec(::l[lst[y]]); y=f[y];
}\quad \quad \}}
while(x!=y){\quad \quad while(x!=y)\{while(x!=y){
w.add(::l[lst[x]]); x=f[x];\quad \quad \quad w.add(::l[lst[x]]);\ x=f[x];w.add(::l[lst[x]]); x=f[x];
w.dec(::l[lst[y]]); y=f[y];\quad \quad \quad w.dec(::l[lst[y]]);\ y=f[y];w.dec(::l[lst[y]]); y=f[y];
}\quad \quad \}}
for(;i<j;++i)\quad \quad for(;i<j;++i)for(;i<j;++i)
A[g[i].r]=w.sum(::r[lst[v[g[i].x]]])−w.sum(::l[lst[v[g[i].x]]]−1);\quad \quad \quad A[g[i].r]=w.sum(::r[lst[v[g[i].x]]])-w.sum(::l[lst[v[g[i].x]]]-1);A[g[i].r]=w.sum(::r[lst[v[g[i].x]]])−w.sum(::l[lst[v[g[i].x]]]−1);
}\quad \}}
for(int i=1;i<=m;++i) printf("%d\n",A[i]);\quad for(int\ i=1;i<=m;++i)\ printf("\%d\backslash n",A[i]);for(int i=1;i<=m;++i) printf("%d\n",A[i]);
}\}}