吐槽:这篇写了几个月的东西终于发出来了(其实是因为太懒了咕了好多题到现在才凑满数量。。。
「Codeforces1257G」Divisor Set-Dilworth定理+分治FFT
2020-02-09
有一个常见的思路是把每个约数看作高维空间上的一个点。每个数向它的约数连边。题目转化为了最长反链,等价于最小链覆盖。
不难发现,这张图以质数的指数和分层,只需要在相邻层连边即可。这样最小链覆盖取决与最大层的大小,即指数和为某个数的约数个数(其实这个数是⌈2n⌉)。
这个是一个背包问题,可以分治NTT解决。每次取出最小次数的两个多项式相乘,可以证明这是O(nlog2n)的。
「Codeforces1286F」Harry The Potter-DP
2020-02-11
这题初看没什么思路,考虑把问题转到图上。
把操作2视作一条连接x,y的边,可以发现这个图是一个森林。因为如果一个联通块S存在≥∣S∣条边,那么全用一操作是不劣的。
称一个集合S是好的,当且仅当这个可以被∣S−1∣次二操作消掉。现在问题转化成了把这张图划分成出尽量多的好的集合。
考虑什么样的集合是好的集合。忽略二操作+1的影响,可以发现奇数层的点权和A等于偶数层的点权和B(证明的话可以以任意一个点为根,可以发现根节点的权值等第二层点的权值-第三层点的权值+第四层点的权值…)
考虑+1的影响,这意味着∣A−B∣<∣S∣并且∣A−B∣≡∣S∣mod2。可以O(3n)+减枝直接DP艹过去。
「Atcoder5762」Preserve Diameter-DP
2020-04-14
我好鸽啊
建出H的BFS树,可以发现
-
T中距离≤1的点之间一定有连边,即相邻、相同层之间一定有边;
-
T中距离>1的点之间一定没有边;
-
H的直径(s,t)只有一条。
由于性质1,2,可以发现只要把图分层,即确定与s的距离dis数组,那么整张图就确定了。所以只要DP出合法的dis数组方案数除以2即可。合法的条件为:
-
diss=0,disi∈[1,d](i=s),且只有一个下标t满足dist=d;
- 若边(u,v)∈G,那么 ∣disu−disv∣≤1。
一种暴力的想法是直接枚举直径起点然后DP。
考虑每条直径一定过直径中点x,那么可以以直径中点为根DP。条件转化为(对于直径长度为偶数特判一下即可):
-
disx=0,disi∈[−2d,2d](i=s),且分别只有一个下标t满足diss=−2d,diss=2d;
- 若边(u,v)∈G,那么 ∣disu−disv∣≤1。
设 mxdi 表示 i 子树内的最大深度,fi,0/1/2,0/1/2 表示以i为根的子树内,有0,1,≥2个点满足disi=mxdi,另一维表示有0,1,≥2个点满足disi=−mxdi,转移时枚举当前边的边权为−1,0,1即可。
「Codeforces666E」Forensic Examination-广义SAM+线段树合并
2020-04-18
一看题,就知道是老套路了
建立串T1..m的广义SAM,然后建立以编号为下标的线段树,对于串 Ti 的每个后缀在下标 i 处 +1。按 fa 树线段树合并就可以统计出每个节点代表的串分别在 T1..m 中出现了多少次。
先预处理 S 每个前缀在广义 SAM 中匹配点,询问时用倍增跳到父亲中最后一个满足 len≥pr−pl+1的点,然后在线段树中查询最大值即可。
「JOISC 2019 Day3」穿越时空 Bitaro-线段树
2020-05-06
JOI 的题好清新啊。
先只考虑从左到右的情况,从右到左把整个序列 reverse 就行了。
有一个非常自然的想法是把题目放到坐标系上。横坐标代表位置,纵坐标代表时间。发下斜向的移动非常麻烦,考虑把涉及到第 i 个点的时间全部减去 i,这样移动时就会变成横线。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x1K3iFv4-1591539484684)(https://s1.ax1x.com/2020/05/06/YVQMEd.png)]
ps.来自官方题解
考虑修改和查询。可以发现对于临近的两个点 i,i+1,设它们的时间区域分别是 [a,b],[c,d]。假设两区间有交,那么 [i,i+1] 的时间区域可以看做 [a,b],[c,d] 的交集。
如果无交,这段路径可以表示为一个三元组 (a,b,c),意味着必须先把时间调到 a 才能走进,然后出来时时间是 b,中间花费的时间是c。比如 Ri<Li+1,那么三元组为 (Ri,Li+1,0);如果 Li>Ri+1,那么三元组为 (Li,Ri+1,Li−Ri+1)。
之后还要考虑三元组/二元组(区间)之间的合并,策略是一样的,即能走就走,否则调时间。
合并显然满足结合率,线段树维护即可。
「APIO2019」路灯-树状数组+cdq分治
2020-05-07
考虑开/关一个路灯对询问的影响。
假设 i 时刻 x 到 x+1 的路灯发生了变化,那么设 x 最左边能走到 p, x+1 最右边能走到 q,那么对于 a∈[p,x],b∈[x+1,q] 的询问,贡献为加上/减去 q−i。值得注意是,当询问时 a,b 联通,还要减去 q−i。(加上/减去 q−i 其实是个差分)。
问题转化为矩形加+单点查。把矩形加差分成四个操作后就是一个三维偏序。
「Gym102341」Infernape-点分治
2020-05-20
显然有一种思路:
ans=i=1∑k∣{u∣∀x∈[1,i)∪(i,k],dis(ax,u)≤bx}∣−∣{u∣∀x∈[1,k],dis(ax,u)≤bx}∣×(k−1)
有一个结论是,对于满足距离两个点 a,b 小于某两个定值 c,d 的点,它一定满足距离另一个点 x 小于 y,并且这是充要条件。
那么要算上面的式子就相当于要算 O(k) 次距离某个点小于一个定值的连通块大小,点分治即可。
「Codechef」JERRYTOM-弦图
2020-05-20
这题解咕到了26号才写。
答案是最大团大小,因为没选最大团老鼠一定可以有地方可以去。否则建立鸡老师考试题里的那棵树,老鼠一定可以被往叶子逼。
具体见 2020-05-14 考试题
「Codeforces449D」Jzzhu and Numbers-FWT
2020-05-26
and 意义下 DWT 是高维前缀和。设 F 表示把 n 个式子 DWT 之后的乘积。这就意味着 Fs=2∑[s&ai=s]。这样高维前缀和之后就可以直接算出 F,然后 IDWT 即可。
「51nod1575」Gcd and Lcm-Min_25筛
2020-06-04
设 f(n) 表示 ∑i=1n∑j=1nlcm(gcd(n,i),gcd(n,j)) 是积性函数。而且 f(pe) 用等比数列求和可以算出来是 (2e+1)(p2e−p2e−1+pe−1),直接 Min_25筛即可。
实际上 ∑i=1n∑j=1nlcm(gcd(n,i),gcd(n,j)) 大力推导一波可以发现是 u∣n∑uv∣un∑μ(v)(x∣uvn∑xϕ(xn))2
是若干个积性函数卷积起来的结果,的确是积性函数。
「Luogu4916」「MtOI2018」魔力环-burnside定理+组合计数
2020-06-06
看到旋转同构,首先套一个 burnside 定理上去:
ans=n∑i=1nf(i)
其中 f(i) 表示旋转 i 次的不动点数量,这等价于 g(gcd(n,i)),其中 g(i) 表示有 i 个循环的方案数。
由于要求每个循环的染色/不染色状态相同,所以如果 m∤i,那么 g(n/i) 一定是 0。
所以
ans=n∑d∣gcd(n,m)g(d)ϕ(n/d)
考虑如何计算 g。考虑 n 个珠子被分为了 n/i 段,同一段之间任意两点属于的循环不同,如下表示n=12,i=4的情况(标号表示属于的循环):
0123|0123|0123
首先特判 n=m 的情况,这样每一段至少有一个珠子没有染色。由于每一段染色情况相同且不合法的段最多横跨两段,所以整个环染色珠子长度不能超过 k,等价于在一个长度为 n/i 的项链上染 m/i 个珠子。
考虑计算把 n 个珠子中的 m 个染色,使得最长染色段不超过 k 方案数。假设强制第一个珠子没有被染色,那么相当于把 m 个染色珠子丢进 n−m 个空隙中,每个空隙不能超过 k 个,容斥即可,设算出的答案为 s。然后由于每个位置都可以是黑色,所以要乘上 n,又因为一种方案被重复计算了 n−m 次,所以要除以 n−m。综上,答案就是 ms×n