退役时的做题计划2

吐槽:这篇写了几个月的东西终于发出来了(其实是因为太懒了咕了好多题到现在才凑满数量。。。


「Codeforces1257G」Divisor Set-Dilworth定理+分治FFT

2020-02-09

有一个常见的思路是把每个约数看作高维空间上的一个点。每个数向它的约数连边。题目转化为了最长反链,等价于最小链覆盖。

不难发现,这张图以质数的指数和分层,只需要在相邻层连边即可。这样最小链覆盖取决与最大层的大小,即指数和为某个数的约数个数(其实这个数是 ⌈ n 2 ⌉ \lceil \frac{n}{2} \rceil 2n)。

这个是一个背包问题,可以分治 N T T NTT NTT解决。每次取出最小次数的两个多项式相乘,可以证明这是 O ( n l o g 2 n ) O(nlog^2n) O(nlog2n)的。


「Codeforces1286F」Harry The Potter-DP

2020-02-11

这题初看没什么思路,考虑把问题转到图上

把操作 2 2 2视作一条连接 x , y x,y x,y的边,可以发现这个图是一个森林。因为如果一个联通块 S S S存在 ≥ ∣ S ∣ \geq |S| S条边,那么全用一操作是不劣的。

称一个集合 S S S是好的,当且仅当这个可以被 ∣ S − 1 ∣ |S-1| S1次二操作消掉。现在问题转化成了把这张图划分成出尽量多的好的集合。

考虑什么样的集合是好的集合。忽略二操作 + 1 +1 +1的影响,可以发现奇数层的点权和 A A A等于偶数层的点权和 B B B(证明的话可以以任意一个点为根,可以发现根节点的权值等第二层点的权值-第三层点的权值+第四层点的权值…)

考虑 + 1 +1 +1的影响,这意味着 ∣ A − B ∣ < ∣ S ∣ |A-B| < |S| AB<S并且 ∣ A − B ∣ ≡ ∣ S ∣ m o d    2 |A-B|\equiv |S| \mod 2 ABSmod2。可以 O ( 3 n ) O(3^n) O(3n)+减枝直接DP艹过去。


「Atcoder5762」Preserve Diameter-DP

2020-04-14

我好鸽啊

建出 H H H B F S BFS BFS树,可以发现

  • T T T中距离 ≤ 1 \leq 1 1的点之间一定有连边,即相邻、相同层之间一定有边;
  • T T T中距离 > 1 > 1 >1的点之间一定没有边;
  • H H H的直径 ( s , t ) (s,t) (s,t)只有一条。

由于性质 1 , 2 1,2 1,2,可以发现只要把图分层,即确定与 s s s的距离 d i s dis dis数组,那么整张图就确定了。所以只要 D P DP DP出合法的 d i s dis dis数组方案数除以 2 2 2即可。合法的条件为:

  • d i s s = 0 , d i s i ∈ [ 1 , d ] ( i ≠ s ) dis_s=0,dis_i \in [1,d](i \neq s) diss=0,disi[1,d](i=s),且只有一个下标 t t t满足 d i s t = d dis_t=d dist=d
  • 若边 ( u , v ) ∈ G (u,v) \in G (u,v)G,那么 ∣ d i s u − d i s v ∣ ≤ 1 |dis_u-dis_v| \leq 1 disudisv1

一种暴力的想法是直接枚举直径起点然后 D P DP DP

考虑每条直径一定过直径中点 x x x,那么可以以直径中点为根 D P DP DP。条件转化为(对于直径长度为偶数特判一下即可):

  • d i s x = 0 , d i s i ∈ [ − d 2 , d 2 ] ( i ≠ s ) dis_x=0,dis_i \in [-\frac {d} {2} ,\frac {d} {2}](i \neq s) disx=0,disi[2d,2d](i=s),且分别只有一个下标 t t t满足 d i s s = − d 2 , d i s s = d 2 dis_s=-\frac {d} {2},dis_s=\frac {d} {2} diss=2d,diss=2d
  • 若边 ( u , v ) ∈ G (u,v) \in G (u,v)G,那么 ∣ d i s u − d i s v ∣ ≤ 1 |dis_u-dis_v| \leq 1 disudisv1

m x d i mxd_i mxdi 表示 i i i 子树内的最大深度, f i , 0 / 1 / 2 , 0 / 1 / 2 f_{i,0/1/2,0/1/2} fi,0/1/2,0/1/2 表示以 i i i为根的子树内,有 0 , 1 , ≥ 2 0,1,\geq 2 0,1,2个点满足 d i s i = m x d i dis_i=mxd_i disi=mxdi,另一维表示有 0 , 1 , ≥ 2 0,1,\geq 2 0,1,2个点满足 d i s i = − m x d i dis_i=-mxd_i disi=mxdi,转移时枚举当前边的边权为 − 1 , 0 , 1 -1,0,1 1,0,1即可。


「Codeforces666E」Forensic Examination-广义SAM+线段树合并

2020-04-18

一看题,就知道是老套路了

建立串 T 1.. m T_{1..m} T1..m的广义SAM,然后建立以编号为下标的线段树,对于串 T i T_i Ti 的每个后缀在下标 i i i + 1 +1 +1。按 f a fa fa 树线段树合并就可以统计出每个节点代表的串分别在 T 1.. m T_{1..m} T1..m 中出现了多少次。

先预处理 S S S 每个前缀在广义 S A M SAM SAM 中匹配点,询问时用倍增跳到父亲中最后一个满足 l e n ≥ p r − p l + 1 len \geq pr-pl+1 lenprpl+1的点,然后在线段树中查询最大值即可。


「JOISC 2019 Day3」穿越时空 Bitaro-线段树

2020-05-06

JOI 的题好清新啊。

先只考虑从左到右的情况,从右到左把整个序列 r e v e r s e reverse reverse 就行了。

有一个非常自然的想法是把题目放到坐标系上。横坐标代表位置,纵坐标代表时间。发下斜向的移动非常麻烦,考虑把涉及到第 i i i 个点的时间全部减去 i i i,这样移动时就会变成横线。

退役时的做题计划2_第1张图片
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x1K3iFv4-1591539484684)(https://s1.ax1x.com/2020/05/06/YVQMEd.png)]

ps.来自官方题解

考虑修改和查询。可以发现对于临近的两个点 i , i + 1 i, i + 1 i,i+1,设它们的时间区域分别是 [ a , b ] , [ c , d ] [a,b],[c,d] [a,b],[c,d]。假设两区间有交,那么 [ i , i + 1 ] [i, i+1] [i,i+1] 的时间区域可以看做 [ a , b ] , [ c , d ] [a,b],[c,d] [a,b],[c,d] 的交集。

如果无交,这段路径可以表示为一个三元组 ( a , b , c ) (a,b,c) (a,b,c),意味着必须先把时间调到 a a a 才能走进,然后出来时时间是 b b b,中间花费的时间是 c c c。比如 R i < L i + 1 R_i < L_{i+1} Ri<Li+1,那么三元组为 ( R i , L i + 1 , 0 ) (R_i,L_{i+1},0) (Ri,Li+1,0);如果 L i > R i + 1 L_i > R_{i+1} Li>Ri+1,那么三元组为 ( L i , R i + 1 , L i − R i + 1 ) (L_i,R_{i+1},L_i-R_{i+1}) (Li,Ri+1,LiRi+1)

之后还要考虑三元组/二元组(区间)之间的合并,策略是一样的,即能走就走,否则调时间。

合并显然满足结合率,线段树维护即可。


「APIO2019」路灯-树状数组+cdq分治

2020-05-07

考虑开/关一个路灯对询问的影响。

假设 i i i 时刻 x x x x + 1 x + 1 x+1 的路灯发生了变化,那么设 x x x 最左边能走到 p p p x + 1 x+1 x+1 最右边能走到 q q q,那么对于 a ∈ [ p , x ] , b ∈ [ x + 1 , q ] a \in [p,x], b \in [x+1,q] a[p,x],b[x+1,q] 的询问,贡献为加上/减去 q − i q - i qi。值得注意是,当询问时 a , b a,b a,b 联通,还要减去 q − i q - i qi。(加上/减去 q − i q - i qi 其实是个差分)。

问题转化为矩形加+单点查。把矩形加差分成四个操作后就是一个三维偏序。


「Gym102341」Infernape-点分治

2020-05-20

显然有一种思路:

a n s = ∑ i = 1 k ∣ { u ∣ ∀ x ∈ [ 1 , i ) ∪ ( i , k ] , d i s ( a x , u ) ≤ b x } ∣ − ∣ { u ∣ ∀ x ∈ [ 1 , k ] , d i s ( a x , u ) ≤ b x } ∣ × ( k − 1 ) ans = \sum_{i=1}^k |\{u| \forall x \in [1,i) \cup (i,k],dis(a_x,u) \leq b_x \}|- \\ |\{u| \forall x \in [1,k],dis(a_x,u) \leq b_x \}|\times (k-1) ans=i=1k{ux[1,i)(i,k],dis(ax,u)bx}{ux[1,k],dis(ax,u)bx}×(k1)

有一个结论是,对于满足距离两个点 a , b a,b a,b 小于某两个定值 c , d c,d c,d 的点,它一定满足距离另一个点 x x x 小于 y y y,并且这是充要条件。

那么要算上面的式子就相当于要算 O ( k ) O(k) O(k) 次距离某个点小于一个定值的连通块大小,点分治即可。

「Codechef」JERRYTOM-弦图

2020-05-20

这题解咕到了26号才写。

答案是最大团大小,因为没选最大团老鼠一定可以有地方可以去。否则建立鸡老师考试题里的那棵树,老鼠一定可以被往叶子逼。

具体见 2020-05-14 考试题


「Codeforces449D」Jzzhu and Numbers-FWT

2020-05-26

a n d and and 意义下 D W T DWT DWT 是高维前缀和。设 F F F 表示把 n n n 个式子 D W T DWT DWT 之后的乘积。这就意味着 F s = 2 ∑ [ s & a i = s ] F_s = 2^{\sum[s \& a_i=s]} Fs=2[s&ai=s]。这样高维前缀和之后就可以直接算出 F F F,然后 I D W T IDWT IDWT 即可。


「51nod1575」Gcd and Lcm-Min_25筛

2020-06-04

f ( n ) f(n) f(n) 表示 ∑ i = 1 n ∑ j = 1 n l c m ( g c d ( n , i ) , g c d ( n , j ) ) \sum_{i=1}^n\sum_{j=1}^n lcm(gcd(n, i), gcd(n, j)) i=1nj=1nlcm(gcd(n,i),gcd(n,j)) 是积性函数。而且 f ( p e ) f(p^e) f(pe) 用等比数列求和可以算出来是 ( 2 e + 1 ) ( p 2 e − p 2 e − 1 + p e − 1 ) (2e+1)(p^{2e}-p^{2e-1}+p^{e-1}) (2e+1)(p2ep2e1+pe1),直接 Min_25筛即可。

实际上 ∑ i = 1 n ∑ j = 1 n l c m ( g c d ( n , i ) , g c d ( n , j ) ) \sum_{i=1}^n\sum_{j=1}^n lcm(gcd(n, i), gcd(n, j)) i=1nj=1nlcm(gcd(n,i),gcd(n,j)) 大力推导一波可以发现是 ∑ u ∣ n u ∑ v ∣ n u μ ( v ) ( ∑ x ∣ n u v x ϕ ( n x ) ) 2 \sum_{u|n} u \sum_{v | \frac{n} {u}} \mu(v) (\sum_{x|\frac{n}{uv}}x\phi(\frac{n}{x}))^2 unuvunμ(v)(xuvnxϕ(xn))2

是若干个积性函数卷积起来的结果,的确是积性函数。


「Luogu4916」「MtOI2018」魔力环-burnside定理+组合计数

2020-06-06

看到旋转同构,首先套一个 b u r n s i d e burnside burnside 定理上去:

a n s = ∑ i = 1 n f ( i ) n ans = \frac{\sum_{i=1}^n f(i)}{n} ans=ni=1nf(i)

其中 f ( i ) f(i) f(i) 表示旋转 i i i 次的不动点数量,这等价于 g ( g c d ( n , i ) ) g(gcd(n,i)) g(gcd(n,i)),其中 g ( i ) g(i) g(i) 表示有 i i i 个循环的方案数。

由于要求每个循环的染色/不染色状态相同,所以如果 m ∤ i m \nmid i mi,那么 g ( n / i ) g(n/i) g(n/i) 一定是 0 0 0

所以

a n s = ∑ d ∣ g c d ( n , m ) g ( d ) ϕ ( n / d ) n ans = \frac{\sum_{d|gcd(n,m)} g(d) \phi (n /d)}{n} ans=ndgcd(n,m)g(d)ϕ(n/d)

考虑如何计算 g g g。考虑 n n n 个珠子被分为了 n / i n/i n/i 段,同一段之间任意两点属于的循环不同,如下表示 n = 12 , i = 4 n=12,i=4 n=12,i=4的情况(标号表示属于的循环):

0123|0123|0123

首先特判 n = m n=m n=m 的情况,这样每一段至少有一个珠子没有染色。由于每一段染色情况相同且不合法的段最多横跨两段,所以整个环染色珠子长度不能超过 k k k,等价于在一个长度为 n / i n/i n/i 的项链上染 m / i m / i m/i 个珠子。

考虑计算把 n n n 个珠子中的 m m m 个染色,使得最长染色段不超过 k k k 方案数。假设强制第一个珠子没有被染色,那么相当于把 m m m 个染色珠子丢进 n − m n-m nm 个空隙中,每个空隙不能超过 k k k 个,容斥即可,设算出的答案为 s s s。然后由于每个位置都可以是黑色,所以要乘上 n n n,又因为一种方案被重复计算了 n − m n-m nm 次,所以要除以 n − m n-m nm。综上,答案就是 s × n m \frac {s \times n} {m} ms×n

你可能感兴趣的:(文章类型——题解)