AtCoder [2000, 3199] 不水

AtCoder [2000, 3199] 不水

https://kenkoooo.com/atcoder/#/list/do_while_true?fromDiff=2200&toDiff=3199

abc294h | C

这位真是重量级!感谢 ZCPB 老师教导!

可以用“广义串并联图方法”,即不断删一度点和二度点,来对图进行简化。删完之后一条边有两个权值,分别代表两端颜色相同/不同时这条边对答案乘上的系数。

对于每个连通块单独考虑。如果点数很小,可以直接枚举颜色的最小表示,也就是爆搜一下集合划分。点数很多的话,非树边会比较少,所以就对于每个返祖边的 dep 较小的点组成的集合,搜这个集合里面的点的颜色的最小表示,然后上个暴力树形 dp 算方案数就行。

复杂度不是很会算,但跑得很快!

Code

arc158d | D

这啥???

摸鱼酱一语切中了肯綮!观察到等式左右两侧都是齐次的,那么自然有 F(tx,ty,tz)=tkF(x,y,z)

假设左边为 F,右边为 GF(tx,ty,tz)=taF(x,y,z),G(tx,ty,tz)=tbG(x,y,z),那么 F(x,y,z)G(x,y,z)=F(tx,ty,tz)G(tx,ty,tz)tba,想令 F(tx,ty,tz)G(tx,ty,tz)=tab.

x,y,z 进行随机,直到 G(x,y,z) 有逆元然后求出 t1,并且还要 t1 能求逆元然后求出 t,就可以了。

arc158e | D

分治,[l,r] 劈成两段 [l,m],[m+1,r],计算跨过 m,m+1 中间这条线的最短路。对左侧每个格子 fx,gx 分别表示到达 (1,m)(2,m) 的最短路(不会回头所以直接 dp),右侧也类似处理出 f,g 是到 (1,m+1),(2,m+1),然后考虑两个格子 x,y 的最短路就是 min(fx+fy,gx+gy),假如是 f 更优那么就是 fx+fy<gx+gyfxgx<gyfy,那就排序,前缀和,二分。

时间复杂度 T(n)=2T(n/2)+O(nlogn)=O(nlog2n)

abc293h | D

编一个看起来挺对的 dp:

fx 表示 x 到子树内的颜色的最大颜色数最小是多少;

gx 表示 x 子树内染色之后的答案。

然后考虑 fx 的转移是让 x 和子树中 f 最大的 u,v 染同样颜色。考虑 g ...... 这时候发现问题了。

g 的转移中 fg 的信息都需要。以为既要对 f chkmax,也要对 g chkmax.贪心肯定是让两个都尽可能小,但是无法定义它们之间的优先级,究竟优先哪个更小是更优的。这样分开记的话,无法得知究竟应该选哪一对 (f,g),只知道最小的 f 和最小的 g 是啥。

一个有点用的观察是直接利用重链剖分构造出答案的上界是 O(logn) 级别的。那么就可以将 f,g 其中一维记在下标里,然后值域里面存另一维最小值是多少。

另外一个思路是考虑二分答案,这样只需要保证 g 满足 mid 即可,然后去 dp f,这样复杂度就是 O(nloglogn) 了。

这个得写下代码才行,青蛙鸽了

arc156d | A

异或有很好的性质,相同直接抵消。那考虑按照将 X 看成多重集来划分等价类,仅大小为奇数的等价类贡献答案。考虑这个多重集的形态,假设下标 i 出现了 ci 次,那么总的出现次数就是:(Kc1,c2,,cn)(多重集的排列数)

欲求其出现次数奇偶性,考察其 2 的次幂是否为 0,仿照 Kummer 定理,容易猜出 2 的次幂为 c1+c2++cn 在二进制下的进位次数,而证明与 Kummer 定理证明几乎一致故略去。那么现在 (Kc1,c2,,cn) 为奇数当且仅当 c1,c2,,cn 两两无交。( Lucas 定理?)

也就是将 K 二进制分解,每个二进制位分配给一个 ci,这样得出来的 c 才是会给答案产生贡献的。

那么思路就转到在数位上考虑,观察到 N,A 都比较小,所以想到设数位 dp fi,j 表示从低到高考虑到第 i 位,总和在第 i 位这里进的位是 j,所有方案的异或是多少。如果这一位是 1 转移就枚举这个 1 分配给哪个 A,然后为了 f 能够转移还要记一下模 2 下的方案数 g

注意到 j 的上界是 i1A2i=O(A),那么时间复杂度是 O(NAlogK)

补一下中间那个证明:

v2(n!)=i1n2i,令 n2i=Si(n)

v2(n!c1!c2!)=i1Si(n)Si(c1)Si(c2)

那么 Si(n) 实际意义为 n 截取最底 i 个二进制位之后的值。

jSi(cj) 实际为所有 c 仅看除去最底 i 个二进制位之后的值再求和。

n=jcj,那么 Si(n)jSi(cj) 即为“所有 c 仅看最底 i 个二进制位求和后再截掉最底 i 位”,也就是在第 i 位进了多少位。

agc061c | C

学习一下不容斥的做法

fi[i,n] 的答案。然后考虑能不能转移,现在考虑选 r 的情况:

对于左端点落在 [li,ri] 的区间,枚举这些区间中第一个选 r 的是哪个区间。如果都选 l 那么方案数就是 fp+1p 是最后一个左端点落在 [li,ri] 的区间编号。

如果枚举了第 j 个区间是第一个选 r 的,现在有 [i+1,j1] 都选的 li 选的是 r,然后考虑 [j+1,n] 的选择方案,首先 [i+1,j1],但是需要 j 是选 r 的,所以记 dpjj 选右端点时 [j,n] 的方案数。然后发现 dpj 中的方案,将 [i,j1] 都插到 ranklist 中得到的方案,与计算 [i,n]j 是第一个选 r 的方案,是一一对应的

(不能一一对应的话就是对于一个 [l,r]ri 在其中,但是没有其它选了的位置在 [l,r] 中,导致选 l 还是选 r 出现了区分。由于题目的特殊性质,ri[l,r] 中那么 rj 一定也在 [l,r] 中,所以不会出现这种情况)

所以就直接令 dpj 转移到 fi 就行。dpi 的转移是几乎一模一样的。

现在考虑 fi 的转移,选 l 的情况,如果直接算 fi+1 的话发现会有算重的,而算重的情况就是 fir[i+1,p] 中的区间都选右的情况,这个就是 dpp 了。

后缀和优化就能做到 O(N)

abc297h | C

先考虑计数怎么做,容斥一下,钦定若个段内部是相等的。那就 dp,fn=i1j1(1)j1fnij,处理出 ai 使得 fn=i=1n1aifni,然后分治 fft 算下就行。

如果要算答案 gn 也一样,gn=i1j1(1)j1(jfnij+gnij),再搞个 bi 就是 gn=i=1n1aigni+i=1n1bifni,分治 fft 一起算 fg 就行。

时间复杂度 O(nlog2n)

arc159c | D

为什么这都想不出来/fn 越来越笨了/fn

考虑操作 k 次那么总和 sum 变成 sum+kn(n1)2,这个需要是 n 的倍数,先考虑 k 是偶数的情况。

现在 k 是偶数有解当且仅当 sumn 的倍数。必要显然,充分就开始构造:

首先发现:

第一步:1 2 3 4 5 ... n-1 n;

第二步;n n-1 ... 5 4 3 2 1.

这样子相当于完全没有变化。然后微调一下:

第一步:1 2 3 4 5 ... n-1 n;

第二步;n-1 n ... 5 4 3 2 1.

这样就实现了第一个减去 1,第二个加上 1.那么用这个玩意把所有数都推成平均值即可。

k 是奇数的话,先随便操作一次,然后变成 k 是偶数的情况,由于无论第一次怎么操作都不会改变操作后的 sum 具体值,所以随便操作一下然后尝试构造就行。

arc153d | A

套路:考虑第 k 位是否进位给 k+1,按照最底下 k 位从大到小排序,能进位的一定是个前缀。那么数位 dp 只需要记当前考虑了前 i 位,第 i 位上有 j 个进位,就能知道哪些进了位,再考虑这一位填啥就行。

arc139d | A

套路:期望可以拆成 >x 的概率之和,即使是计数问题也一样,>x 的方案数之和。

然后就考虑 >x 的有多少个的方案数,加起来就是答案,这个统计就很简单了。假如现在有 cx,那么每轮就有 x 种方案 cc+1,有 (Mx) 种方案 c 不变,然后 c 再和 X1 取 min,按照初始时 cX1 的大小分类讨论,枚举 K 次操作中有几次是取到 x 的值即可统计方案数。

abc309h | D

折线容斥的新思路?!

首先是个格路计数问题,尝试反射容斥无果。

每上一层可以往左走或者中间走或者往右走,看上去就很想让答案多项式去乘一个 (x1+1+x1),那需要在模 (xM1) 意义下做,那么现在问题。。。

posted @   do_while_true  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2022-03-23 「杂谈」原来我不会差分约束
2022-03-23 一些经典小结论

This blog has running: 1837 days 12 hours 56 minutes 19 seconds

点击右上角即可分享
微信分享提示