Bzoj2434 阿狸的打字机

134 篇文章 0 订阅
42 篇文章 0 订阅

纪念一次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 &lt; s t d i o . h &gt; \#include&lt;stdio.h&gt; #include<stdio.h>
# i n c l u d e &lt; s t r i n g . h &gt; \#include&lt;string.h&gt; #include<string.h>
# i n c l u d e &lt; a l g o r i t h m &gt; \#include&lt;algorithm&gt; #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 &lt; = n ; x + = x &amp; − x )   + + w [ x ] ;   } \quad inline\ void\ add(int\ x)\{\ for(;x&lt;=n;x+=x\&amp;-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 &lt; = n ; x + = x &amp; − x )   − − w [ x ] ;   } \quad inline\ void\ dec(int\ x)\{\ for(;x&lt;=n;x+=x\&amp;-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 &amp; = x − 1 )   v + = w [ x ] ;   r e t u r n   v ;   } \quad inline\ int\ sum(int\ x)\{\ for(v=0;x;x\&amp;=x-1)\ v+=w[x];\ return\ v;\ \} inline int sum(int x){ for(v=0;x;x&=x1) 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 &lt; &lt; 1 ] ; struct\ edge\{\ int\ v,nt;\ \}\ G[N&lt;&lt;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 &amp; &amp; ! s [ p ] [ c ] ; p = f [ p ] )   s [ p ] [ c ] = n p ; \quad \quad for(;p\&amp;\&amp;!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 &lt; &lt; 2 ) ; \quad \quad \quad memcpy(s[nq],s[q],26&lt;&lt;2); memcpy(s[nq],s[q],26<<2);
f o r ( ; p &amp; &amp; s [ p ] [ c ] = = q ; p = f [ p ] )   s [ p ] [ c ] = n q ; \quad \quad \quad for(;p\&amp;\&amp;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 &lt; = c n t ; + + i ) { \quad \quad for(int\ i=2;i&lt;=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 &lt; b . y ;   } inline\ bool\ cv(V\ a,V\ b)\{\ return\ a.y&lt;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==&#x27;B&#x27;)\{\ ++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==&#x27;P&#x27;)\{\ 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-=&#x27;a&#x27;])\ 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 ( &quot; % s % d &quot; , S , &amp; m ) ; \quad scanf(&quot;\%s\%d&quot;,S,\&amp;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 &lt; = r ; + + l ) { \quad for(int\ x;l&lt;=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 &lt; 26 ; + + i ) \quad \quad for(int\ i=0;i&lt;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 &lt; = m ; + + i )   s c a n f ( &quot; % d % d &quot; , &amp; g [ i ] . x , &amp; g [ i ] . y ) , g [ i ] . r = i ; \quad for(int\ i=1;i&lt;=m;++i)\ scanf(&quot;\%d\%d&quot;,\&amp;g[i].x,\&amp;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 &lt; = m ; ) { \quad for(int\ x,y=1,i=1,j=1;i&lt;=m;)\{ for(int x,y=1,i=1,j=1;i<=m;){
w h i l e ( j &lt; = m   &amp; &amp;   g [ j ] . y = = g [ i ] . y )   + + j ; \quad \quad while(j&lt;=m\ \&amp;\&amp;\ 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[i1].y];
w h i l e ( d [ x ] &gt; d [ y ] ) { \quad \quad while(d[x]&gt;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 ] &gt; d [ x ] ) { \quad \quad while(d[y]&gt;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 &lt; j ; + + i ) \quad \quad for(;i&lt;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 &lt; = m ; + + i )   p r i n t f ( &quot; % d \ n &quot; , A [ i ] ) ; \quad for(int\ i=1;i&lt;=m;++i)\ printf(&quot;\%d\backslash n&quot;,A[i]); for(int i=1;i<=m;++i) printf("%d\n",A[i]);
} \} }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值