Atcoder试题乱做 Part2

感受下来, 思维难度有参差, 所以还是可以做的, 虽然有的题和中国赛题差距有点大, 但是无伤大雅?

新的 Part 我要自己做出来更多题!


[AGC014D]Black and White Tree

[EASY]

发现点一个叶子结点的父亲变白点, 那这个叶子就一定要点黑点, 然后这两个点就对其他的部分不造成影响了, 可以删掉, 所以如果一个点有两个叶子结点儿子, 那么直接就是先手胜利.


[AGC004F]Namori

[NORMAL]

树的话是, 经典套路奇偶层染色, 变成交换草走. 那么就可以考虑一个子树里面需要移进多少, 移出多少, 分值为 1,1 , 那么就可以定义 ai 为这个子树内值的和. 显然根不为 0 无解, 答案下界为 i=1n|ai| , 不难构造这就是最优答案.

接着考虑基环树, 偶环的时候考虑环边是 uv , 假定这个边会操作 x 次, 那么一边的父亲操作会多 x 次, 另一边少 x 次, 断掉这个边之后按树跑出 ai , 答案即为:

ileft|aix|+iright|aix|+|x|

就是求解中位数.

如果是奇环, 那么那个环边就可以让黑点数量 +2 或者 2 , 所以只要黑点白点数量差为偶数, 就一定可以通过调和来让整张图有解.

直接给答案和那条环边的两个点加上全图黑点与白点的差除以 2 , 然后按树的做法即可.


[AGC028D]Chords

[EASY]

n=2N , 这个圆看成序列也是一样的, 如果 [l1,r1][l2,r2] 相交但不包含, 就在一个连通块.

考虑计算每个连通块对答案的贡献次数. 令 fi,j 表示区间 [i,j] 任意连边, 且 ij 在同一个连通块内的方案数.

枚举这样的区间, 区间长度一定是偶数, 设 gx 表示 x 个点的环任意连边的方案数, ci,j 表示 [i,j] 内还没确定连边情况的点的个数.

转移为 fi,j=gci,jk=i+1j1fi,kgck+1,j , 答案为 fi,jgn2kci,j , 时间复杂度 O(n3) .


[AGC007E]Shik and Travel

[EASY]

比较简单的一道题.

显然可以二分, 一条边恰好经过两次, 所以只能走完一棵子树, 再去走另一个. 考虑 dp , 设 fx,u,v 表示从结点 x 开始, 第一个走到的叶子结点距离为 u , 走回 x 时的距离为 v , 路径上所有长度不大于二分值的情况下遍历完整个子树, 是否可行.

转移很显然, 然后发现当满足 a1a2,b1b2 时, fx,a2,b2 完全没有存在的必要, 故按 u 排序后 v 递减时数量最少.

可以分析合并次数, 只在轻边的时候会合并, 合并 log 次, 故状态总数为 nlogn 个.

时间复杂度 O(nlog2n) .


[AGC052D]Equal LIS

[NORMAL]

挺好猜的, 但确实不好构造.

令原排列的 LIS 长度为 l .

l 为偶数, 那么直接令 fi 为以 i 结尾的最长上升子序列长度, 将 fil2 的放入第一个序列, 其他的放入第二个序列即可.

否则 l 为奇数, 即 l=2k+1 , 那么对于其中一个长度为 lLIS , 要存在一个元素 x 不在此序列中, 且存在一个长度为 k+1 的上升子序列包含它.

这个条件的必要性显然, 充分性构造如下.

任选一个长度为 lLIS , 根据这个性质, 选择 x 并假设这个 k+1 的上升子序列为 p1,p2,,pk+1 .

将所有满足 1jk+1 , fifpjfi=fxix 的选入第一个序列, 其余的选入第二个序列.

第二个序列中, 所有的 pi 都被选入, 并且只有 k+1 种不同的 f 取值, 即不存在 k+2 的上升子序列, 故构成 k+1 的上升子序列.

第一个序列中, 由于总共只有 2k+1f 的取值, 所以第一个序列中包含 k+1 种取值, 故也构成 k+1 的上升子序列.

关于判定, 求出每一个元素为起点和终点的最长上升子序列, 即可求出强制包含某个元素的最长上升子序列, 判定其是否大于等于 k+1 即可.

时间复杂度 O(nlogn) .


[AGC006C]Rabbit Exercise

[EASY]

若选中点 a , 则期望的新位置为 (2xa+1xa)+(2xa1xa)2=xa+1+xa1xa .

根据期望的可加性, Ea=Ea+1+Ea1Ea , 这个式子只有加减, 涉及的项也相邻, 考虑差分.

令差分数组为 d , 不难发现 Ea=Ea1+di+1 , 所以 di=di+1.di+1=di , 实际上是交换了差分数组位置.

那一次大操作就是一个置换, 我们可以单 log 类似快速幂的做, 也可以做到线性.

具体来说就是把置换拆成若干个循环, 循环要移动的距离其实就是 kmodsize 位, 递推即可.

时间复杂度 O(n) .


[AGC009E]Eternal Average

[NORMAL]

我觉得很巧妙, 是不可多得的好题.

把问题写成 k 叉树的形式, 一共 n+m 片叶子其中 n 片写着 0 , m 片写着 1 . 对于一个非叶子结点, 它的值为它儿子的值的平均值.

假设那 n0 的深度分别为 xi , m1 的深度分别为 yi , 则根结点的值就是 i=1m(1k)yi , 并且我们知道, 假设所有点都是 1 , 会有 i=1n(1k)xi+i=1m(1k)yi , 若满足这两个条件, 则一定能构成合法的 k 叉树.

我们把 i=1m(1k)yi 写成 k 进制下的小数形式, Z=(0.z1z2)k , 即 m(1k)yi 相加, 而 (1Z) 则可以表示 n(1k)xi 相加, 不考虑进位, 则 zi=m , 考虑还原进位则将 zi 减去 1 并将 zi+1 加上 k , 所以 zi+a(k1)=m , 即 zim(modk1) , 假设小数有 len 位, 则 1Z 的位数和应该是 (len1)(k1)+kzi=len(k1)zi+1 .

接下来就可以 dp 方案数了, 设 fi,j,0/1 表示 len=i , zi=j , zi 是否为 0 , 转移很简单.

fi,j,0=fi1,j,0+fi1,j,1fi,j,1=x=1kfi1,jx,0+fi1,jx,1

前缀和优化一下即可, 时间复杂度 O(n2) .


[AGC041D]Problem Scores

[NORMAL]

感觉还是有点巧妙的, 但也算是去单调性的常用做法.

首先应该先把第三个限制转化, 最开始我只转化为了前 k+1 个的和要大于后 k 个的和, 但是很明显的发现, 并不好 dp , 所以肯定还要转化一下.

但是显然只看限制三是已经没有前途的了, 结合限制一来看, 我们发现, 因为有单调性的限制, 所以我们只用考虑中点是否符合限制即可.

即需满足 i=1n2+1aii=nn2+1nai , 简单证明一下, 对于小于 n2 的位置, 左边减去一个较小的数, 右边减去一个较大的数, 仍满足, 对于大于 n2 的数, 左边加上一个较大的数, 右边加上一个较小的数, 仍满足, 当然这个的前提是有单调性.

但是有这个单调性我们还是不好做, 继续考虑转化, 我们考虑差分去掉这个单调性, 令 Δai=aiai1 , 为了不让 Δa1 很奇怪, 我们令 a0=1 , 这样每个 ai 实际上就是 ai=1+i=1iΔai .

整理一下式子,

i=1n2j=1iΔaji=nn2+1nj=1iΔaj

向下取整会影响一点东西, 但其实问题不大, 还是分类一下吧.

对于 n 是奇数时, n2 就是 n12 , 整理,一下式子

i=1n+12j=1iΔaji=n+12+1nj=1iΔaj2i=1n+12j=1iΔaji=1nj=1iΔaj2i=1n+12(n+12i+1)Δaii=1n(ni+1)Δaii=1nciΔai0

其中, ci={i2,in+12ni+1,i>n+12 .

同样的, 考虑偶数, 最后可以推出来 ci={i2,in2+1ni+1,i>n2+1 , 综合一下得到, ci={i2,in2+1ni+1,i>n2+1 .

好, 现在我们只有限制二没用上了, 即 Δai+1n , 我们发现有的序列是本质相同的, 使得它不同的原因是 Δa1 .

于是我们考虑确定 Δa2Δan 的值的时候有多少合法的 Δa1 , 有两个条件 {Δa1n1i=2nΔaiΔa1i=2nciΔai , 所以合法的个数就是 max{0,ni=2n(ci+1)Δai} .

我们令 fii=2n(ci+1)Δai=i 的个数, 那么最终答案就是 i=0n1(ni)fi .

不难发现计算 fi 就是一个背包, 第 i 个物品重量为 ci+1 , 做无限背包, 时间复杂度 O(n2) .


[AGC041F]Histogram Rooks

[HARD]

toohardforme , 题解差评, 不应该强加笛卡尔树上去的, 容斥检验成果题? 成果检查到不合格.

最初想法, 枚举哪些格子没有被覆盖, 然后对于一个位置如果行列都没有被钦定未覆盖的格子, 那么方案数是 2 .

复杂度爆炸.

注意到如果一个格子被钦定未被覆盖, 那么他所在的列一定不能放棋子, 行有机会可以放, 重新设计容斥方案.

枚举哪些列里面有格子是未被覆盖的, 那么这些列都不可以放棋子, 设这些列的集合为 S .

此时考虑一个极长行连续段的贡献, 假设有 p 个格子在 S 里, 那么贡献有两种.

  1. p 个格子可以被覆盖, 方案数 2lenp .
  2. 枚举有几个格子是未覆盖的, 方案数为 i=1p(pi)(1)i=[p0] .

但这样算出来会是错的, 因为 S 里的列可能没有被钦定的格子.

再套上一个容斥, 枚举集合 TS , 表示没有被钦定的格子.

设一个极长连续段里面有 q 个格子在 T 里, 那么第二种贡献变成 [pq] .

注意到此时贡献只和 p,[pq] 有关, 所以状态数不会太大.

每次从 h 最小的地方切开, 下面是一个矩形, 上面是子问题, 且子问题是树形结构, 矩形里的连续段就是上面的子问题加单独算的列.

于是设 fx,p,0/1 表示树上的结点 x , S 的大小为 p , 是否有 pq .

转移背包合并即可, 独有的列可以看做特殊的儿子, 此时每一列方案数是相同的, 快速幂即可.

时间复杂度 O(n2logn) , 预处理后 O(n2) .


[AGC043D]Merge Triplets

[EASY]

挺有意思的一道题的, 不算难, 其实多想一会应该是能想出来的, 可惜想这题的时候想了一会就摆了.

首先发现, 能构造出来的序列有一个显然的必要条件, 一个数作为新排列的前缀 max 的时候, 长度不会超过 3 , 并且如果存在长度为 3 的段, 那它在原排列中一定在一组里, 但这个条件并不充分.

既然不会超过 3 , 那我们关注一下 长度为 21 的, 可以发现, 如果存在一个长度为 2 的, 首先这两数一定在同一组, 并且那一组一定存在一个长度为 1 的.

这时候我们应该敏锐的考虑同组的在新排列的前缀 max 序列中的构成, 长度为 3 , 或者是三个长度为 1 的, 或者是一个长度为 2 的和一个长度为 1 的, 最后一种前后顺序并不重要, 一定是会有合法构成方案的.

这时候充分条件就很显然了, 长度为 2 的段数不超过长度为 1 的段数.

考虑如何计数, 由于只关注长度为 2 的段数和长度为 1 的段数差, 所以可以设 fi,j 表示考虑前 i 个数, 长度为 1 的段数减去长度为 2 的段数值为 j 的方案数.

如果 ai[1,r] 中是最大的, 对于长度为 n 的排列, 答案就是 n!r , 转移的时候带到系数里即可.

时间复杂度 O(n2) .


这个 Part 也让我成长了不少啊.

posted @   Lonely923  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示