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即可。
T2 Third
我的一种奇怪做法,正经一些的是利用矩阵。
先考虑20分的暴力。对于每个询问我们都搞出真正的序列。
令\(f(i,c)\)表示考虑到\(i\),结尾字符为\(c\)的本质不同子序列数量。
原理:原本本质不同的序列的末尾加入该字符后仍本质不同,以及一个仅包含\(c\)的子序列。
每次询问复杂度\(\mathcal O(nc).\)
考虑本题询问的特性,若将原序列复制一份接在后面,(并将询问离线)就相当于每次询问 \(c+A_{pos+1...pos+n}\) 的\(f(n,d)\).
相当于我们要支持,在末尾加一个字符,在开头加一个字符,在开头删除一个字符和询问\(f(n,d)\)。
重定义\(f(s,t)\)为:在当前维护的序列上,以\(s\)开头,以\(t\)结尾的本质不同序列数量。
末尾加字符\(a_i\):
开头加字符\(c\),实际上没必要真的去更新\(f\),而只需回答\(\sum_xf(x,d).\)
开头删除字符\(x=a_{i-n+1}\),这个有点毒瘤。考虑逆进行开头加字符的操作(令\(g\)为删除该字符前的\(f\)值):
顺便维护\(s_x=\sum_{y}f(x,y),t_x=\sum_y f(y,x)\) 就可以做到移动一格复杂度为\(\mathcal O(m)\),单次询问复杂度\(\mathcal O(m)\)
My code