山东省队集训 2022 Day1 T1
设 fu,i,0/1 代表 u 填了 i,u 的子树内满足条件且最大值在 / 不在 u 处取到的方案数.
对于 0 的情况,转移显然.对于 1 的情况,枚举在哪棵子树中取到最大值,统计方案.
这个复杂度有点寄,甚至过不了 50 分.加一车前缀和之后可以过.
正解就是这个换下根.嘴巴会了,没写代码.
山东省队集训 2022 Day2 T1
怎么连着两场都只有 T1 有分?
积木大赛的结论是区间正差分和.在平衡树上维护 ai−ai−1 和 ai−ai+1 即可支持区间翻转.撤销操作建操作树即可.注意修改的边界讨论.
可能是我写丑了,这题代码超级 /tuu,赛时还没调出来.ckain 赛时过掉了,拜谢 ckain.
补补补.题解.
补补补.题解.
发现是计算询问是计算 φ.设 n=∏i=1spiki,有 φ(n)=n×∏i=1spipi−1.
于是在线段树上维护区间乘积和区间质因数出现情况,第二个可以状压存.
设 fi,j 表示考虑了人数 ≤i 的组,已经使用了 j 个人的方案数.
转移时枚举当前人数分的组数 k,c≤k≤d,有转移方程:
fi,j=fi−1,j+k∑(ikn−(j−ik))×fi−1,j−ik×h(i,j)
其中 h(i,j) 代表人数为 i 的组分 k 个的方案数,即
h(i,j)=j!1p∏(iik−ip)
容易预处理.然后就可以 O(n2logn) 地 DP 了.
多串匹配,首先建出 AC 自动机.
设 fi,u 表示前 i 位匹配到 u 节点的概率.有转移:
fi+1,v=fi,u/∣Σ∣
其中 v 代表匹配后走到的节点.注意匹配不能交,每次匹配后要走到 0.
DP 过程中每次匹配时统计答案,然后放矩阵里快速幂.
首先二项式反演一下,算钦定 k 对非平局的方案.
设 fu,i 表示 u 子树内钦定 k 对点的方案数.子树的方案树上背包转移一下,然后分讨当前点的颜色,计算从自己子树中选一个异色点的方案数.
巨大推式题.题解.
发现一个权值为 x 的点能被走到的充要条件为:到根的链上所有作为左儿子的节点,其父亲的权值 >x;所有作为右儿子的节点,其父亲的权值 <x.
轻重链剖分维护每个点是哪个儿子和作为左 / 右儿子节点的父亲节点的权值的 minmax
,然后就能转子树了.
8 MB,强制在线.考虑分块.
bitset 存颜色出现情况,块间建 ST,卡卡空间.没了.
大家写分治 FFT 都这么鬼畜的吗?题解.
令 f(x)=(ax+b)modn.考虑每个 Ti 能够贡献到的 p.
若 Ti=1,有 f(x)∈[0,c),解得 x∈[−ia,c−ia).
若 Ti=0,有 f(x)∈[c,n),解得 x∈[c−ia,n−ia).
其中的诡异记号 x 表示 x 在模 n 意义下.
搞棵动态开点线段树维护.
先二分转化成判定性问题.
子树同构,一眼哈希.但是常用的树哈希方式并不支持限制深度的子树查询.
但是这题中树的儿子是有序的!这启发我们对括号序进行哈希.
对深度为 k 的子树的括号序哈希可以通过枚举深度为 k+1 的儿子然后去除不需要的部分,剩下拼接起来.
这个复杂度是对的,因为每个点只会是一个点的深度为 k 的儿子,那么枚举量就是 O(n) 的.
难以发现那个两端都在 / 不在区间内的限制其实是没有用的,至少我没看出来.
考虑将限制放松为只有一个端点在区间内,然后不等式两边会有一个相同的量,可以消掉.
那么我们设 cti 表示 i 开始的 exciting 路径条数,这个可以点分治计算.
答案就是求满足
i∈[l,r]∑wi>i∈[l,r]∑wi
的区间 [l,r] 个数.有单调性,双指针统计一下.
令元素 i 的出现次数为 cti.
观察到如果游戏胜利,最终抽出的序列一定前面单调增,最后一个和倒数第二个元素相同.
考虑设 fi,j 表示在递增部分已经填了 i 个元素,最后一个元素填 j 的概率.枚举递增序列长度 i 和最后一个元素 j,那么答案就是
i=0∑n−1j∑fi,j×n−ictj−1
枚举上一个数填什么,f 的转移显然:
fi,j=n−i+1ctjk<j∑fi−1,k
然后前缀和搞一下.
这个随机选数并上去的操作相当于每次在一堆集合中选一个并到自己上去,求的就是自己变成全集的期望步数.
若设随机变量 xi 表示 i 被选到的步数,那么我们就是要求 E(maxi∈Sxi),其中 S 是全集.这个形式非常 min-max 容斥啊!那么转化成求
T⊂S∑(−1)∣T∣−1E(i∈Tminxi)
考虑如何求后半部分那个期望,记 f(S)=E(mini∈Sxi),再记 p(S)=∑T⊂SpT,其中 pT 代表选中集合 T 的概率,那么有:
f(S)=i=1∑∞i×p(S)×(1−p(S))i−1
这也是经典问题!错位相减可得 f(S)=p(S)1.那么只需要处理子集和就行了,这个可以 FWT 解决.
先暴力打不同 p 下 SG(x) 的表,发现在 p 是奇数的情况下,SG(x)=xmod2.在 p 是偶数的情况下
SG(x)={2xmod(p+1)mod2x≡p(mod(p+1))otherwise
推到了结论之后,暴力循环展开,卡卡取模次数好像就能过.网上题解说的分块做法没咋看,以后补.
先考虑链的情况怎么做,发现整棵树是由两根链拼成的,这两条链之内的元素都构成祖先关系,不能放到一个段中.那么贪心地合并链即可.具体地,我们为两条链分别维护两个堆,每次取出两个堆中最大的元素,这两个元素需要放到一个段中,加到答案上就行.容易证明这个策略是正确的.
树的情况类似,按照贪心策略启发式合并每棵子树的堆,然后把本轮合并出的段当成元素塞到合并完的堆里即可.复杂度不会算.
这个部分直接照抄的 PPT.
直接把所有元素塞在一起排序.为了匹配极大,我们钦定不会被匹配的奶牛和牛棚,并要求这些牛棚在奶牛之前.
设 fi,j,0/1 表示当前考虑了前 i 大的元素,且有 j 头未被钦定不被匹配奶牛还没有被分配,目前是否钦定过不被匹配奶牛.
- 若当前元素是牛棚,转移没有钦定过不被匹配奶牛的状态时,可以让这个牛棚空着,钦定过的状态则不能空着,必须匹配此前的一头牛.有转移
fi,j,0fi,j,1=fi−1,j,0+(j+1)fi−1,j+1,0=(j+1)fi−1,j+1,1
- 若当前元素是奶牛,转移没有钦定过不被匹配奶牛的状态时,当前奶牛只能塞进待匹配的奶牛中,钦定过的状态则可以抛弃当前奶牛.有转移
fi,j,0fi,j,1=fi−1,j−1,0=fi−1,j−1,0/1+fi−1,j,1
首先计算操作次数 m=2∑ibi,若不能整除则无解.
考虑设 fi,full,part 表示前 i 位已经变成一样的,使用了 full 次完整的操作,part 次一半的操作(只操作一个位置)的方案数,容易进行转移.
状态数都是 O((∑ibi)3) 的,看似没法优化.然而我们发现,对于合法的状态,一定有
part=k=1∑ibk−2×full
那么状态就可以只记录 full,转移时计算半个操作的数目 part 和空闲操作的数目 none,枚举当前补上前面的 k 个半个操作,有转移
fi,full+k←fi−1,full×(kpart)×(bi−knone)
设 f(x) 表示长度为 x 的子序列数目,g(x) 为长度 ≥x 的子序列数目,那么答案为
x∑xf(x)=x∑i=1∑xf(x)=i∑x≥i∑f(x)=x∑g(x)
那么考虑求 g(i).注意到方案和顺序无关,于是先把 ai 排序.外层枚举 x,设 fi,j 表示考虑了前 i 个元素,长度为 j 的子序列数目.转移枚举 p,使得 ai−ap≥x,有转移 fi,j←fp,j−1.由于 a 有序,p 单调增,求和区间是一个前缀,前缀和优化即可.
单次 DP 时间复杂度 O(nk),外层只用枚举到 k−1maxiai,故总复杂度 O(nmaxiai).
首先长度不同的串肯定不会在一个方案中出现,于是按照长度分类考虑.
其次我们把字符串集合中的串翻转之后塞回去,新集合中的字符串就是所有合法字符串.
发现边上的字符貌似不是很重要,因为边上的字符实际上是被角上的字符约束住了,方案数可以预处理.
考虑如何写暴力.预处理 wx,y 表示 x 开头 y 结尾的合法字符串个数,枚举 8 个角上的字符,把每条边的方案乘起来求和.这样做的复杂度是 O(∣Σ∣8),T 飞了.
考虑减少枚举量.好像有很多枚举实际上是没有用的!我们可以直接不去枚举最后一个点填什么,然后预处理一个 fx,y,z 表示有一个点没有确定,与这个点相邻的点分别填了 x,y 和 z 的方案数,直接乘上去就行.
发现如果一个点的相邻的点上的字符全都确定了,那么他的邻边方案可以直接用预处理的值,我们称这样的点被覆盖了.然后对于正方体上的 8 个顶点,我们只用 4 个点就可以全部覆盖.选取 2 个对面不共面的对角线的 4 个端点枚举即可.
lxl 给的确定性做法,很有趣!
考虑区间 [l,r] 内的元素能够被重排为等差数列有那些条件:
- maxi=lrai−mini=lrai=k(r−l).
- 相邻两数差的绝对值是 k 的倍数.
- 区间内没有重复数字.
条件 1 可以通过维护区间最值判定,条件 2 可以通过维护差分数组 gcd 来判定,条件 3 可以通过维护每个数字上一次出现位置来判定.都可以修改!
感觉不如哈希.
树上最大权独立集问题有一个经典做法,设 fu,0/1 表示考虑了 u 的子树,u 是否选的最大权独立集.转移显然.
这题要对方案计数,考虑一个 DP 套 DP.设 Fu,i,j 表示考虑了 i 的子树,fu,0=i,fu,1=j 的方案数.有转移
Fu,i,j+Fv,s,t→Fu,max{i+s,i+t},j+t
看起来很对!但是状态数炸了.
进行一个性质的观察,发现 0 状态不会比 1 状态小很多.为了减少外层 DP 的状态数目,我们重新设计内层 DP 的状态.设 gu,0/1 表示考虑 u 的子树,是否钦定不选 u 的最大权独立集.发现 gu,1∈[gu,0−k,gu,0],这样外层 DP 的只用记录 gu,0 和 gu,0−gu,1.
注意到由于保镖只能往左边看,所以点 r 上一定会有一个保镖.
然后计算点 r 上向左看到的最后一个位置 p,则 [p,r] 中的所有亭子都已经被看到了.且 [l,p−1] 中的亭子都看不到.这就将原问题拆成了两个子问题,若设 fl,r 表示覆盖区间 [l,r] 的最小代价,那么有转移 fl,r←max{fl,p−1,fl,p}+fp,r.
枚举 r 之后 l 往左扫就可以做到 O(n2).
船新 DP 技巧.
令覆盖区间表示一个方案中第一个磁铁和最后一个磁铁构成的区间.
如果我们能够计算出覆盖区间长度为 x 的方案个数,记作 f(x),那么考虑将剩下的空位往磁铁中间插,这个部分的方案就是
(nl−x+n)f(x)
那么问题转化为求 f(x).
首先按照 ri 升序插入磁铁,这样只用考虑插入的磁铁吸引前面已经放下的磁铁.
设 fi,j,k 表示当前考虑了 r 前 i 小的磁铁,这些磁铁被分为了 j 组,每组互不影响,总覆盖长度为 k 的方案数.
转移考虑 i+1 对当前分组造成的影响,有:
- 插入到某一组的某一端,有转移 fi,j,k×2j→fi+1,j,k+ri+1.
- 新建组,有转移 fi,j,k×(j+1)→fi+1,j+1,k+1.
- 合并两个组,有转移 fi,j,k×(j−1)→fi+1,j−1,k+2ri+1−1.
最终我们要将所有分组合并,有 f(x)=fn,1,x.
观察样例发现很多点的答案是一样的!答案不一样的点貌似分布在两条链上!
继续观察可以发现,链尾的两个节点权值的异或和就是全局异或最大值.
于是就有做法了.先把全局异或最大值和构成最大值的点对弄出来,只有这两个点到根的路径上答案会不同.暴力处理两根链上的答案即可.
观察到最后求的是排名的方案数,而不是可能的 bi 的分配方式,这启发我们去考虑如何刻画可行的最终排列这一信息.
考虑如何判定一个排列可行.我们可以贪心地使分配的 bi 尽量的小,多的部分可以全部扔给最后一个人.
直接抛出结论,对于最终排列 p,最优的 bi 分配方式为 bi=bi−1+max{api−1−api,0}.
那么考虑设 fS,x,i 表示已经考虑了 S 中的元素,最后一个考虑的元素是 x,当前的 ∑kbk 是 i 的方案数,转移考虑加入一个 S 中没有的元素 y,对 ∑kbk 的影响为 (n−∣S∣)×(max{ax−ay+[y>x],0}),那么有转移
fS,x,i→fS∪{y},y,i+(n−∣S∣)×(max{ax−ay+[y>x],0})
初始化时注意第一个被考虑的元素需要盖过原序列中的最大值.