◊ \Large{\color{red}\Diamond} ◊ 为重点转换步骤。
直接设 f i , j f_{i,j} f i , j 表示前 S [ 1 ∼ i ] S[1 \sim i] S [ 1 ∼ i ] 匹配 T [ 1 ∼ j ] T[1\sim j] T [ 1 ∼ j ] 位的答案。
f i , j = min ( f i − 1 , j + 1 , f i , j − 1 + 1 , f i − 1 , j − 1 + [ S i = T j ] ) f_{i,j}=\min(f_{i-1,j}+1,f_{i,j-1}+1,f_{i-1,j-1}+[S_i\not=T_j])
f i , j = min ( f i − 1 , j + 1 , f i , j − 1 + 1 , f i − 1 , j − 1 + [ S i = T j ] )
直接做复杂度为 O ( ∣ S ∣ m ∣ T ∣ ) \mathcal O(|S|m|T|) O ( ∣ S ∣ m ∣ T ∣ ) 。
由于 ∣ T ∣ ≤ 20 |T|\le 20 ∣ T ∣ ≤ 2 0 ,并且发现 i − j ≤ f i , j ≤ i + j i-j\le f_{i,j}\le i+j i − j ≤ f i , j ≤ i + j ,所以 i + j − f i , j ≤ 2 ∣ T ∣ i+j-f_{i,j}\le2|T| i + j − f i , j ≤ 2 ∣ T ∣ ,由于值域范围小,所以套路性的将值域放在定义维上,将原本的 i i i 定为 dp 值。◊ \Large{\color{red}\Diamond} ◊
设 g i , j g_{i,j} g i , j 为满足 f x , i = x + i − j f_{x,i}=x+i-j f x , i = x + i − j 最小的 x x x 。
上面的 f f f 的转移式中前两种方法的 i + j − f i , j i+j-f_{i,j} i + j − f i , j 是不变的,所以先 g i , j ← g i − 1 , j g_{i,j} \leftarrow g_{i-1,j} g i , j ← g i − 1 , j 。
若想让 S i = T j S_i=T_j S i = T j ,g i , j ← k ( k > g i − 1 , j − 2 , S k = T j ) g_{i,j} \leftarrow k(k>g_{i-1,j-2},S_k=T_j) g i , j ← k ( k > g i − 1 , j − 2 , S k = T j ) ,否则 g i , j ← k ( k > g i − 1 , j − 1 , S k ≠ T j ) g_{i,j} \leftarrow k(k>g_{i-1,j-1},S_k\neq T_j) g i , j ← k ( k > g i − 1 , j − 1 , S k = T j ) 。
预处理出每个位置 n x i , j , 0 / 1 nx_{i,j,0/1} n x i , j , 0 / 1 表示 S i S_i S i 后字符为/不为 j j j 的第一个位置。
本题保证了无重边自环。
k = 1 k=1 k = 1 简单。
将 ∑ f ( S ) 2 \sum f(S)^2 ∑ f ( S ) 2 转成 ∑ ( f ( S ) 2 ) \sum \binom{f(S)}2 ∑ ( 2 f ( S ) ) ,赋予组合意义即为从 S S S 的导出子图中任意选两条边的方案数的和,从而可以拆贡献至选取两条边进行计算。◊ \Large{\color{red}\Diamond} ◊
f ( S ) 2 = 2 ( f ( S ) 2 ) + f ( S ) f(S)^2=2\binom{f(S)}2+f(S)
f ( S ) 2 = 2 ( 2 f ( S ) ) + f ( S )
两条边的情况可能是两条无交边或有一个公用顶点,分开讨论并枚举公共点即可。
f ( S ) 3 = 6 ( f ( S ) 3 ) + 3 f ( S ) 2 − 2 f ( S ) f(S)^3=6\binom{f(S)}3+3f(S)^2-2f(S)
f ( S ) 3 = 6 ( 3 f ( S ) ) + 3 f ( S ) 2 − 2 f ( S )
f ( S ) 2 f(S)^2 f ( S ) 2 和 f ( S ) f(S) f ( S ) 直接使用上面的即可,重点讨论 ( f ( S ) 3 ) \binom{f(S)}3 ( 3 f ( S ) ) 如何拆开。
影响结果的只有任选的三条边的点数 x x x 和方案数 y y y ,贡献为 y 2 n − x y2^{n-x} y 2 n − x 。
x = 3 , 4 , 5 , 6 x={3,4,5,6} x = 3 , 4 , 5 , 6 。由于总方案数为 ( m 3 ) \binom{m}3 ( 3 m ) ,所以 x = 6 x=6 x = 6 可以直接用总的减去其它的计算。
x = 3 x=3 x = 3 ,即一个三元环。直接用三元环计数即可,令方案数为 A A A ,复杂度为 O ( m m ) O(m\sqrt m) O ( m m ) 。
x = 4 x=4 x = 4 ,可能是一条链或者一个菊花。
链:枚举中间那一条边 ( u , v ) (u,v) ( u , v ) ,方案数 B = ( ∑ ( d e g u − 1 ) × ( d e g v − 1 ) ) − 3 A B=(\sum (deg_u-1)\times (deg_v-1))-3A B = ( ∑ ( d e g u − 1 ) × ( d e g v − 1 ) ) − 3 A ,最后减 3 A 3A 3 A 是因为如果形成三元环,每条边都会被作为中间的边多算一次。
菊花:枚举度数为 3 3 3 的点 u u u ,方案数 C = ∑ ( d e g u 3 ) C=\sum \binom{deg_u}{3} C = ∑ ( 3 d e g u ) 。
x = 5 x=5 x = 5 ,即分离的一条三元链和一条边,枚举三元链的中心 u u u ,方案数 D = ( ∑ ( d e g u 2 ) ( m − 2 ) ) − 3 A − 2 B − 3 C D=(\sum\binom{deg_u}2(m-2))-3A-2B-3C D = ( ∑ ( 2 d e g u ) ( m − 2 ) ) − 3 A − 2 B − 3 C 。
3 A 3A 3 A 因为三元环中三个点都会被作为链中心,2 B 2B 2 B 因为插入的新边可能在链的两端,3 C 3C 3 C 因为菊花的三条边都会被作为插入的新边。
x = 6 x=6 x = 6 ,E = ( m 3 ) − A − B − C − D E=\binom m 3-A-B-C-D E = ( 3 m ) − A − B − C − D 。
( f ( S ) 3 ) = 2 n − 3 A + 2 n − 4 ( B + C ) + 2 n − 5 D + 2 n − 6 E \binom {f(S)}3=2^{n-3}A+2^{n-4}(B+C)+2^{n-5}D+2^{n-6}E ( 3 f ( S ) ) = 2 n − 3 A + 2 n − 4 ( B + C ) + 2 n − 5 D + 2 n − 6 E 。
寻找第 k k k 小可以先转化成二分答案 + 求有多少个 ≤ m i d \le mid ≤ m i d 。k ← k − 1 k\leftarrow k-1 k ← k − 1
这里的字典序有些不同,可以直接用 A i A_i A i 记录 i i i 出现的次数,比较 A A A 和 B B B 时从 i = 1 → n i=1\to n i = 1 → n 比较 A i A_i A i 和 B i B_i B i 即可,若 A i < B i A_i<B_i A i < B i 则 A > B A>B A > B ,A i > B i A_i>B_i A i > B i 则 A < B A<B A < B 。
由于增加一个数一定会使字典序变小,所以 S [ l , l ] > S [ l , l + 1 ] > . . . > S [ l , n ] S[l,l]>S[l,l+1]>...>S[l,n] S [ l , l ] > S [ l , l + 1 ] > . . . > S [ l , n ] 且 S [ 1 , r ] < S [ 2 , r ] < . . . S [ r , r ] S[1,r]<S[2,r]<...S[r,r] S [ 1 , r ] < S [ 2 , r ] < . . . S [ r , r ] ,于是对于左端点固定的区间具有单调性,设二分的区间是 [ L , R ] [L,R] [ L , R ] ,则可以通过双指针或二分对每个 i i i 求出 M i M_i M i 使 S [ i , n ] < S [ i , n − 1 ] < . . . < S [ i , M i ] ≤ S [ L , R ] S[i,n]<S[i,n-1]<...<S[i,M_i]\le S[L,R] S [ i , n ] < S [ i , n − 1 ] < . . . < S [ i , M i ] ≤ S [ L , R ] ,进而求出 S [ L , R ] S[L,R] S [ L , R ] 的排名。◊ \Large{\color{red}\Diamond} ◊
若 r n k ( S [ L , R ] ) ≤ k rnk(S[L,R])\le k r n k ( S [ L , R ] ) ≤ k ,则将 p r i = M i − 1 pr_i=M_i-1 p r i = M i − 1 表示删去 [ i , M i ] , [ i , M i + 1 ] . . . [ i , n ] [i,M_i],[i,M_i+1]...[i,n] [ i , M i ] , [ i , M i + 1 ] . . . [ i , n ] ,并将 k ← k − r n k ( S [ L , R ] ) k\leftarrow k-rnk(S[L,R]) k ← k − r n k ( S [ L , R ] ) 。否则将 p l i = M i pl_{i}=M_i p l i = M i 表示删去 [ i , i ] , [ i , i + 1 ] , . . . [ i , M i − 1 ] [i,i],[i,i+1],...[i,M_i-1] [ i , i ] , [ i , i + 1 ] , . . . [ i , M i − 1 ] 。
生成 [ L , R ] [L,R] [ L , R ] 时在剩余的所有区间中随机一个即可,期望每次能选到字典序排名的重点左右,所以复杂度是 O ( log n ) O(\log n) O ( log n ) 的。
双指针的过程就是有 O ( n ) O(n) O ( n ) 次加入和删除一个字符,并查询桶内第一个和 S [ l , r ] S[l,r] S [ l , r ] 的桶内的不同值。可以使用线段树维护 T i = A i − B i T_i=A_i-B_i T i = A i − B i ,加入字符 c c c 时将 T c ← T c + 1 T_c\leftarrow T_c+1 T c ← T c + 1 ,删除时 T c ← T c − 1 T_c \leftarrow T_c-1 T c ← T c − 1 ,查询时在线段树上二分或提前存储第一个 T i ≠ 0 T_i\neq0 T i = 0 ,若 T i > 0 T_i>0 T i > 0 则 A < B A<B A < B ,否则 A > B A>B A > B 。总复杂度为 O ( n log 2 n ) O(n\log^2n) O ( n log 2 n ) 。
设 L i , j , R i , j , U i , j , D i , j L_{i,j},R_{i,j},U_{i,j},D_{i,j} L i , j , R i , j , U i , j , D i , j 分别表示 ( i , j ) (i,j) ( i , j ) 向左,向右,向上,向下能走到的最远的位置。
原题就是求
∑ i = 1 n ∑ j = 1 m ∑ x = U i i − 1 ∑ y = L j j − 1 [ D x , y ≥ i ∧ R x , y ≥ j ] \sum_{i=1}^n\sum_{j=1}^m\sum_{x=U_i}^{i-1}\sum_{y=L_j}^{j-1}[D_{x,y}\ge i\wedge R_{x,y}\ge j]
i = 1 ∑ n j = 1 ∑ m x = U i ∑ i − 1 y = L j ∑ j − 1 [ D x , y ≥ i ∧ R x , y ≥ j ]
明显上面的式子是四维的,无法直接做。将矩阵进行分治,选择竖着的中线 m i d mid m i d ,分别对左右独立讨论经过中线的方案数再乘起来,将四维转换为三维。◊ \Large{\color{red}\Diamond} ◊
两边情况相似,只考虑左侧穿过中线的情况。先枚举 u ∈ [ 1 , n ] , v ∈ ( u , n ] u\in[1,n],v\in (u,n] u ∈ [ 1 , n ] , v ∈ ( u , n ] ,计算左侧选取的 匚 的数量。
于是现在只要求
∑ u = L R ∑ v = u + 1 R ∑ x = max ( l , L u , m i d , L v , m i d ) m i d − 1 [ D u , x ≥ v ] \sum_{u=L}^R\sum_{v=u+1}^R\sum_{x=\max(l,L_{u,mid},L_{v,mid})}^{mid-1}[D_{u,x}\ge v]
u = L ∑ R v = u + 1 ∑ R x = max ( l , L u , m i d , L v , m i d ) ∑ m i d − 1 [ D u , x ≥ v ]
枚举完 u , v u,v u , v 后分类讨论 max ( l , L u , m i d ) \max(l,L_{u,mid}) max ( l , L u , m i d ) 和 max ( l , L v , m i d ) \max(l,L_{v,mid}) max ( l , L v , m i d ) 哪个更大,若前者更大,则对于所有 u u u 询问的区间已经固定,所以只要开一个桶记录 D u , x D_{u,x} D u , x 的后缀个数和。如果是后者更大,就相当于求 ∑ x = max ( l , L v , m i d ) m i d − 1 [ U v , x ≤ u ] \displaystyle\sum_{x=\max(l,L_{v,mid})}^{mid-1}[U_{v,x}\le u] x = max ( l , L v , m i d ) ∑ m i d − 1 [ U v , x ≤ u ] ,处理方式和上面类似,开另一个桶记录 U v , x U_{v,x} U v , x 的前缀个数和。这样就能单次 O ( 1 ) O(1) O ( 1 ) 解决。
设 l e n = r − l + 1 , L E N = R − L + 1 len=r-l+1,LEN=R-L+1 l e n = r − l + 1 , L E N = R − L + 1 ,这样单次的复杂度为 O ( L E N 2 + l e n × L E N ) \mathcal O(LEN^2+len\times LEN) O ( L E N 2 + l e n × L E N ) ,由于分治时面积每次一定会减半,所以递归层数为 O ( log 2 n m ) \mathcal O(\log_2nm) O ( log 2 n m ) 。若能保证 L E N ≤ l e n LEN\le len L E N ≤ l e n 则单次复杂度为 O ( l e n × L E N ) \mathcal O(len\times LEN) O ( l e n × L E N ) ,此时总复杂度正确。每次递归后若 L E N > l e n LEN>len L E N > l e n 则从 [ l , r ] [l,r] [ l , r ] 中间取中线变为从 [ L , R ] [L,R] [ L , R ] 中间取中线,复杂度为 O ( n m log 2 n m ) \mathcal O(nm\log_2nm) O ( n m log 2 n m ) 。
多树问题和距离问题考虑点分治和点分树。
点分树的性质:原树上 u , v u,v u , v 的路径会经过点分树上的 L C A ( u , v ) LCA(u,v) L C A ( u , v ) ,所以 d i s ( x , y ) = d i s ( x , L C A ′ ( x , y ) ) + d i s ( L C A ′ ( x , y ) , y ) dis(x,y)=dis(x,LCA'(x,y))+dis(LCA'(x,y),y) d i s ( x , y ) = d i s ( x , L C A ′ ( x , y ) ) + d i s ( L C A ′ ( x , y ) , y ) ,L C A ′ LCA' L C A ′ 表示在点分树上的 lca。◊ \Large{\color{red}\Diamond} ◊
考虑对第一棵树进行点分治,若当前分治中心为 r t rt r t ,已经处理过的点集为 S S S ,当前需要求 u u u 到 S S S 的答案。设 i i i 以 r t rt r t 为根的深度为 a i a_i a i ,则需要求 min v ∈ S a u + a v + d i s 2 ( u , v ) \min_{v\in S} a_u+a_v+dis_2(u,v) min v ∈ S a u + a v + d i s 2 ( u , v ) ,由点分治的性质可得
\min_{v\in S} a_u+a_v+dis_2(u,v)=\min_{v\in S}a_u+a_v+dis_2(u,LCA_{2'}(u,v))+dis_2(LCA_{2'}(u,v),v) \\
=\min_{v\in S,x=LCA_{2'}(u,v)}(a_u+dis_2(u,x))+(a_v+dis_2(v,x)) & \Large{\color{red}\Diamond}
x x x 为点分树上 u u u 和 v v v 的祖先,所以 x x x 只有 O ( log 2 n ) \mathcal O (\log_2n) O ( log 2 n ) 个,当将 v v v 加入 S S S 时,跳过 v v v 的每个祖先 x x x 并将 a v + d i s 2 ( v , x ) a_v+dis_2(v,x) a v + d i s 2 ( v , x ) 的贡献挂在 x x x 上,u u u 查询时只要将挂在所有祖先的贡献加上 a u + d i s 2 ( u , x ) a_u+dis_2(u,x) a u + d i s 2 ( u , x ) 后求最大值即可,若 u , v u,v u , v 在 x x x 的同一颗子树内,则长度只会更大,不影响最小值更新。
复杂度为 O ( n log 2 n ) \mathcal O(n\log^2n) O ( n log 2 n ) ,瓶颈在点分治和在点分树上跳祖先。
正难则反。先容斥一下,考虑计算有多少方案使得没有一个点能被 1 , 2 1,2 1 , 2 同时到达。◊ \Large{\color{red}\Diamond} ◊
令 f S f_S f S 表示只保留 S S S 导出子图并给其定向,1 1 1 恰好能到达 x ∈ S x\in S x ∈ S 的方案数,g S g_S g S 和 f S f_S f S 同理,从 2 2 2 号点出发,w ( S ) w(S) w ( S ) 表示 S S S 的导出子图的边数。
a n s = 2 m − ∑ S ∩ T = ∅ f S g T 2 w ( U − S − T ) ans=2^m-\sum_{S \cap T=\empty}f_Sg_T2^{w(U-S-T)}
a n s = 2 m − S ∩ T = ∅ ∑ f S g T 2 w ( U − S − T )
由于 S ∩ T = ∅ S\cap T=\empty S ∩ T = ∅ ,所以只需枚举 T ⊆ U − S T\sube U-S T ⊆ U − S 即可,复杂度为 O ( 3 n ) \mathcal O(3^n) O ( 3 n ) 。
思考如何求 f , g f,g f , g ,同样用总方案数 2 w ( S ) 2^{w(S)} 2 w ( S ) 减去不合法的。
先枚举 T ⊂ S T\sub S T ⊂ S ,计算只能到达 T T T 的方案数。内部可达为 f T f_T f T ,外部 S − T S-T S − T 的导出子图随意,一条边 ( u , v ) , u ∈ T , v ∈ S − T (u,v),u\in T,v\in S-T ( u , v ) , u ∈ T , v ∈ S − T 的只能定向为 ( v , u ) (v,u) ( v , u ) ,所以方案数为 2 w ( S − T ) f T 2^{w(S-T)}f_T 2 w ( S − T ) f T ,枚举子集复杂度也是 O ( 3 n ) \mathcal O(3^n) O ( 3 n ) 。
总复杂度为 O ( 3 n ) \mathcal O(3^n) O ( 3 n ) 。