THUWC前集训Day3

THUWC前集训Day3

T1 Second

后缀的LCP,第一反应就是先建后缀树。

考虑在后缀树上dp。令(f(u))表示(u)的子树的答案(不考虑该子树外的所有后缀和点,并要求子树内所有后缀权值和为1)。

(u)表示一个后缀,显然(f(u)=0.)否则依次考虑(u)的所有儿子(v). 若只有一个儿子(v,f(u)=f(v)+len(v)-len(u).)

否则,若给(v)的子树分配的权值和为(x),则(f(u)=max((1-x)f(u),x(f(v)+len(v)-len(u)))).显然max中的两个值相等时最优。

复杂度(O(n)),若用sam建有点卡空间,但实现的时候不必真正建出后缀树,依照拓扑序做dp即可。

My code

T2 Third

我的一种奇怪做法,正经一些的是利用矩阵。

先考虑20分的暴力。对于每个询问我们都搞出真正的序列。

(f(i,c))表示考虑到(i),结尾字符为(c)的本质不同子序列数量。

[f(i,c)=1+sum_xf(i-1,x) ]

原理:原本本质不同的序列的末尾加入该字符后仍本质不同,以及一个仅包含(c)的子序列。

每次询问复杂度(mathcal O(nc).)

考虑本题询问的特性,若将原序列复制一份接在后面,(并将询问离线)就相当于每次询问 (c+A_{pos+1...pos+n})(f(n,d)).

相当于我们要支持,在末尾加一个字符,在开头加一个字符,在开头删除一个字符和询问(f(n,d))

重定义(f(s,t))为:在当前维护的序列上,以(s)开头,以(t)结尾的本质不同序列数量。

末尾加字符(a_i)

[f'(s,a_i)=[s=a_i]+sum_{x}f(s,x)\ ]

开头加字符(c),实际上没必要真的去更新(f),而只需回答(sum_xf(x,d).)

[f(a_i,d)=[a_i=d]+sum_xf(x,d) ]

开头删除字符(x=a_{i-n+1}),这个有点毒瘤。考虑逆进行开头加字符的操作(令(g)为删除该字符前的(f)值):

[f(x,t)=[x=t]+sum_yg(y,t)\ Rightarrow g(x,t)=f(x,t)-[x=t]-sum_{x e y}g(y,t) ]

顺便维护(s_x=sum_{y}f(x,y),t_x=sum_y f(y,x)) 就可以做到移动一格复杂度为(mathcal O(m)),单次询问复杂度(mathcal O(m))
My code

原文地址:https://www.cnblogs.com/oierwanhong/p/14163846.html