纪念一次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]);
}
放个
L
a
T
e
X
LaTeX
LaTeX版本的代码恶心人~
#
i
n
c
l
u
d
e
<
s
t
d
i
o
.
h
>
\#include<stdio.h>
#include<stdio.h>
#
i
n
c
l
u
d
e
<
s
t
r
i
n
g
.
h
>
\#include<string.h>
#include<string.h>
#
i
n
c
l
u
d
e
<
a
l
g
o
r
i
t
h
m
>
\#include<algorithm>
#include<algorithm>
#
d
e
f
i
n
e
N
200010
\#define\ N\ 200010
#define N 200010
u
s
i
n
g
n
a
m
e
s
p
a
c
e
s
t
d
;
using\ namespace\ std;
using namespace std;
s
t
r
u
c
t
f
e
n
w
i
c
k
{
struct\ fenwick\{
struct fenwick{
i
n
t
w
[
N
]
,
n
,
v
;
\quad int\ w[N],n,v;
int w[N],n,v;
i
n
l
i
n
e
v
o
i
d
i
n
i
t
(
i
n
t
c
)
{
n
=
c
;
}
\quad inline\ void\ init(int\ c)\{\ n=c;\ \}
inline void init(int c){ n=c; }
i
n
l
i
n
e
v
o
i
d
a
d
d
(
i
n
t
x
)
{
f
o
r
(
;
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]; }
i
n
l
i
n
e
v
o
i
d
d
e
c
(
i
n
t
x
)
{
f
o
r
(
;
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]; }
i
n
l
i
n
e
i
n
t
s
u
m
(
i
n
t
x
)
{
f
o
r
(
v
=
0
;
x
;
x
&
=
x
−
1
)
v
+
=
w
[
x
]
;
r
e
t
u
r
n
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;
i
n
t
h
[
N
]
,
c
n
t
=
1
,
d
[
N
]
,
l
[
N
]
,
r
[
N
]
,
c
l
k
,
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];
i
n
t
s
[
N
]
[
26
]
,
l
s
t
[
N
]
,
v
[
N
]
,
n
,
m
,
t
o
t
=
1
,
n
c
,
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];
s
t
r
u
c
t
e
d
g
e
{
i
n
t
v
,
n
t
;
}
G
[
N
<
<
1
]
;
struct\ edge\{\ int\ v,nt;\ \}\ G[N<<1];
struct edge{ int v,nt; } G[N<<1];
n
a
m
e
s
p
a
c
e
S
A
M
{
namespace\ SAM\{
namespace SAM{
i
n
t
s
[
N
]
[
26
]
,
m
x
[
N
]
,
f
[
N
]
,
c
n
t
=
1
;
\quad int\ s[N][26],mx[N],f[N],cnt=1;
int s[N][26],mx[N],f[N],cnt=1;
i
n
l
i
n
e
i
n
t
e
x
t
e
n
d
(
i
n
t
p
,
i
n
t
c
)
{
\quad inline\ int\ extend(int\ p,int\ c)\{
inline int extend(int p,int c){
i
n
t
n
p
=
+
+
c
n
t
,
q
,
n
q
;
\quad \quad int\ np=++cnt,q,nq;
int np=++cnt,q,nq;
m
x
[
n
p
]
=
m
x
[
p
]
+
1
;
\quad \quad mx[np]=mx[p]+1;
mx[np]=mx[p]+1;
f
o
r
(
;
p
&
&
!
s
[
p
]
[
c
]
;
p
=
f
[
p
]
)
s
[
p
]
[
c
]
=
n
p
;
\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;
i
f
(
!
p
)
{
f
[
n
p
]
=
1
;
r
e
t
u
r
n
n
p
;
}
\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];
i
f
(
m
x
[
q
]
=
=
m
x
[
p
]
+
1
)
f
[
n
p
]
=
q
;
\quad \quad if(mx[q]==mx[p]+1)\ f[np]=q;
if(mx[q]==mx[p]+1) f[np]=q;
e
l
s
e
{
\quad \quad else\{
else{
n
q
=
+
+
c
n
t
;
\quad \quad \quad nq=++cnt;
nq=++cnt;
m
x
[
n
q
]
=
m
x
[
p
]
+
1
;
\quad \quad \quad mx[nq]=mx[p]+1;
mx[nq]=mx[p]+1;
f
[
n
q
]
=
f
[
q
]
;
f
[
q
]
=
f
[
n
p
]
=
n
q
;
\quad \quad \quad f[nq]=f[q];\ f[q]=f[np]=nq;
f[nq]=f[q]; f[q]=f[np]=nq;
m
e
m
c
p
y
(
s
[
n
q
]
,
s
[
q
]
,
26
<
<
2
)
;
\quad \quad \quad memcpy(s[nq],s[q],26<<2);
memcpy(s[nq],s[q],26<<2);
f
o
r
(
;
p
&
&
s
[
p
]
[
c
]
=
=
q
;
p
=
f
[
p
]
)
s
[
p
]
[
c
]
=
n
q
;
\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 \}
}
r
e
t
u
r
n
n
p
;
\quad \quad return\ np;
return np;
}
\quad \}
}
i
n
l
i
n
e
v
o
i
d
d
f
s
(
i
n
t
x
)
{
\quad inline\ void\ dfs(int\ x)\{
inline void dfs(int x){
l
[
x
]
=
+
+
c
l
k
;
\quad \quad l[x]=++clk;
l[x]=++clk;
f
o
r
(
i
n
t
i
=
h
[
x
]
;
i
;
i
=
G
[
i
]
.
n
t
)
d
f
s
(
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
]
=
c
l
k
;
\quad \quad r[x]=clk;
r[x]=clk;
}
\quad \}
}
i
n
l
i
n
e
v
o
i
d
b
u
i
l
d
T
r
e
e
(
)
{
\quad inline\ void\ buildTree()\{
inline void buildTree(){
f
o
r
(
i
n
t
i
=
2
;
i
<
=
c
n
t
;
+
+
i
)
{
\quad \quad for(int\ i=2;i<=cnt;++i)\{
for(int i=2;i<=cnt;++i){
G
[
+
+
:
:
c
n
t
]
=
(
e
d
g
e
)
{
i
,
h
[
f
[
i
]
]
}
;
h
[
f
[
i
]
]
=
:
:
c
n
t
;
\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 \}
}
d
f
s
(
1
)
;
\quad \quad dfs(1);
dfs(1);
}
\quad \}
}
}
\}
}
c
h
a
r
S
[
N
]
,
∗
T
;
char\ S[N],*T;
char S[N],∗T;
s
t
r
u
c
t
V
{
i
n
t
x
,
y
,
r
;
}
g
[
N
]
;
struct\ V\{\ int\ x,y,r;\ \}\ g[N];
struct V{ int x,y,r; } g[N];
i
n
l
i
n
e
b
o
o
l
c
v
(
V
a
,
V
b
)
{
r
e
t
u
r
n
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; }
i
n
l
i
n
e
v
o
i
d
B
t
r
i
e
(
i
n
t
x
)
{
inline\ void\ Btrie(int\ x)\{
inline void Btrie(int x){
i
f
(
!
∗
T
)
r
e
t
u
r
n
;
\quad if(!*T)\ return;
if(!∗T) return;
i
f
(
∗
T
=
=
′
B
′
)
{
+
+
T
;
r
e
t
u
r
n
;
}
e
l
s
e
\quad if(*T=='B')\{\ ++T;\ return;\ \}\ else
if(∗T==′B′){ ++T; return; } else
i
f
(
∗
T
=
=
′
P
′
)
{
v
[
+
+
n
c
]
=
x
;
+
+
T
;
B
t
r
i
e
(
x
)
;
}
\quad if(*T=='P')\{\ v[++nc]=x;\ ++T;\ Btrie(x);\ \}
if(∗T==′P′){ v[++nc]=x; ++T; Btrie(x); }
e
l
s
e
{
\quad else\{
else{
i
f
(
!
s
[
x
]
[
∗
T
−
=
′
a
′
]
)
s
[
x
]
[
∗
T
]
=
+
+
t
o
t
;
\quad \quad if(!s[x][*T-='a'])\ s[x][*T]=++tot;
if(!s[x][∗T−=′a′]) s[x][∗T]=++tot;
f
[
t
o
t
]
=
x
;
d
[
t
o
t
]
=
d
[
x
]
+
1
;
B
t
r
i
e
(
s
[
x
]
[
∗
T
+
+
]
)
;
B
t
r
i
e
(
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 \}
}
}
\}
}
i
n
t
m
a
i
n
(
)
{
int\ main()\{
int main(){
s
c
a
n
f
(
"
%
s
%
d
"
,
S
,
&
m
)
;
\quad scanf("\%s\%d",S,\&m);
scanf("%s%d",S,&m);
T
=
S
;
B
t
r
i
e
(
1
)
;
\quad T=S;\ Btrie(1);
T=S; Btrie(1);
i
n
t
l
=
1
,
r
=
0
;
l
s
t
[
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;
f
o
r
(
i
n
t
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];
f
o
r
(
i
n
t
i
=
0
;
i
<
26
;
+
+
i
)
\quad \quad for(int\ i=0;i<26;++i)
for(int i=0;i<26;++i)
i
f
(
s
[
x
]
[
i
]
)
{
\quad \quad \quad if(s[x][i])\{
if(s[x][i]){
l
s
t
[
s
[
x
]
[
i
]
]
=
S
A
M
:
:
e
x
t
e
n
d
(
l
s
t
[
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 \}
}
S
A
M
:
:
b
u
i
l
d
T
r
e
e
(
)
;
w
.
i
n
i
t
(
S
A
M
:
:
c
n
t
)
;
\quad SAM::buildTree();\ w.init(SAM::cnt);
SAM::buildTree(); w.init(SAM::cnt);
f
o
r
(
i
n
t
i
=
1
;
i
<
=
m
;
+
+
i
)
s
c
a
n
f
(
"
%
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;
s
o
r
t
(
g
+
1
,
g
+
1
+
m
,
c
v
)
;
v
[
0
]
=
1
;
\quad sort(g+1,g+1+m,cv);\ v[0]=1;
sort(g+1,g+1+m,cv); v[0]=1;
f
o
r
(
i
n
t
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;){
w
h
i
l
e
(
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];
w
h
i
l
e
(
d
[
x
]
>
d
[
y
]
)
{
\quad \quad while(d[x]>d[y])\{
while(d[x]>d[y]){
w
.
a
d
d
(
:
:
l
[
l
s
t
[
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 \}
}
w
h
i
l
e
(
d
[
y
]
>
d
[
x
]
)
{
\quad \quad while(d[y]>d[x])\{
while(d[y]>d[x]){
w
.
d
e
c
(
:
:
l
[
l
s
t
[
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 \}
}
w
h
i
l
e
(
x
!
=
y
)
{
\quad \quad while(x!=y)\{
while(x!=y){
w
.
a
d
d
(
:
:
l
[
l
s
t
[
x
]
]
)
;
x
=
f
[
x
]
;
\quad \quad \quad w.add(::l[lst[x]]);\ x=f[x];
w.add(::l[lst[x]]); x=f[x];
w
.
d
e
c
(
:
:
l
[
l
s
t
[
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 \}
}
f
o
r
(
;
i
<
j
;
+
+
i
)
\quad \quad for(;i<j;++i)
for(;i<j;++i)
A
[
g
[
i
]
.
r
]
=
w
.
s
u
m
(
:
:
r
[
l
s
t
[
v
[
g
[
i
]
.
x
]
]
]
)
−
w
.
s
u
m
(
:
:
l
[
l
s
t
[
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 \}
}
f
o
r
(
i
n
t
i
=
1
;
i
<
=
m
;
+
+
i
)
p
r
i
n
t
f
(
"
%
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]);
}
\}
}