Atcoder abc235
https://atcoder.jp/contests/abc235/tasks
G - Gardens
A个种子1
B个种子2
C个种子3
N个花园
要满足条件, 任何花园都有种种子
每个花园每种的个数[0,1]
不需要把所有都种植
求方案数mod 998244353
范围
n 5e6
3s
1024mb
我的思路
R(i,j) 表示,i个花园,种完其中j个花园的方案数
T(n) 表示,n个花园,恰好种满这n个花园的方案数, T(n) = R(n,n)
ans = T(n)
S(n) = R(n,n) + R(n,n-1) + R(n,n-2) + … + R(n,0);
S(n) = R(n,n) * binom(n,n) + R(n-1,n-1) * binom(n,n-1) + .. + R(0,0) * binom(n,0)
S(n) = T(n) * binom(n,n) + T(n-1) * binom(n,n-1) + .. + T(0) * binom(n,0)
S(n) 很容易算, 相当于A,B,C互不影响, = prod (sum binom(n,0..X)), X=A,B,C, 问题是这个依赖于n需要O(n),
如果能反过来得到T(n) 就好了
T(n) = S(n) - (T(n-1) * binom(n,n-1) + … + T(0) * binom(n,0))
T(n)/n! = S(n)/n! - sum T(i)/i!/(n-i)!
考虑花园状态只有2^3-1=7 种,那么就是 七种中,总个数小于a,b,c的
生成方程?
$\sum \lbrack pwr_x\le a,pwr_y\le b,pwr_z\le c \rbrack ((1+x)(1+y)(1+z)-1)^n$
$= \sum_{i\in[0, n],i_x\le a,,i_y\le b,i_z\le c} (-1)^{n-i} \binom{n}{i} \binom{i}{i_x}\binom{i}{i_y}\binom{i}{i_z} $
$= \sum_{i\in[0, n],i_x\le a,,i_y\le b,i_z\le c} (-1)^{n-i} \binom{n}{i} \binom{i}{min(i,i_x)}\binom{i}{min(i,i_y)}\binom{i}{min(i,i_z)} $
并没法算
再就是, 假设 a<=b<=c
ans(a,b,c) 通过 ans(b,b,b) 让每次头-1,或者尾+1,多次得到
去考虑之间的变化
题解
看来我容斥原理完全不会了, 题目是容斥得到了 我通过生成方程得到的表达式
然后 也是, 如果暴力, 枚举i,总的是O(n^2) 时间
$f(M,N) = \sum_{i=0}^{min(N,M)} \binom{N}{i}$
哦 我好蠢, 这相当于M取值只会是a,b,c, 所以针对性的 只有N变化!!
因此可以O(1)算出 $f(M,N+1) = \sum_{i=0}^{min(N+1,M)} \binom{N+1}{i}$
对于$N\le M$显然 $ f(M,N) = 2^N$
直接定义无效的binom=0
考虑sum(i,0..X) 到 sum(i+1,0..X)的增量
显然$f(M,N) = 2f(M,N-1) + binom{N,M}$
代码
https://atcoder.jp/contests/abc235/submissions/34663174
1 |
|
Ex - Enumerate Pairs
n点m边无向有边权图,
初始所有点黑色,你可以做最多k次操作
每次操作: 任选点v和数x, 把所有从v出发只经过<=x的边可达的所有点染红
问最终染红的点的集合 有多少种集合, mod 998244353
范围
n 1e5
m 1e5
k 500
ci [1,1e9]
3s
1024mb
我的思路
显然x更大的时候, 如果u,v不能连通,那么更小的时候也不能联通
因此联通关系随着x变大, 相当于并查集合并的感觉
考虑把每个点变成叶子,当距离为0时,就是每个节点单独成
然后把边排序,从小到大做合并, 最多n-1次, 因为每合并一次个数-1
问题是这样每个里面点数也是O(n) 整体要n^2空间
考虑直接用树来表示
为了 A,B,C 在达到某个长度x时,合成了一起
所以树上的根节点还要记录合并时的长度
这样问题变成了, 有一个2n量级节点的树, 每次选一个节点,染色它的所有子节点, 问叶子节点被染色的集合的方案数, 一共k次操作
树问题, 变成树上dp?
f(u,t) = 节点u以及它的子节点 操作k次后的集合状态
染u则 1种
不染u则 需要计算不全染的方案数, 子节点数 > t 考虑乘积组合, 子节点数<=t, 则乘积组合后再减去1
dp[i][j] =
,前i个节点, 染了j次的方案数
`dp[i][j] = sum dp[i-1][l=0..j] * f(p[i],j-l)
感觉复杂度炸了
题解
一样的, 建树, 然后树上DP
注意到这里并没说是连通图, 所以是建森林然后DP, 树内和森林dp都是同样的dp转移式
就直接暴力就好了
证明复杂度不是nk^2,而是nk
考虑连接两个联通块, 它们各自的节点数
- 节点数都多于K个, 这样最多O(N/K)次, N/K * K ^2 = NK
- 节点数都少于K个, 这样把所有少于k个的操作代价累计, 在它们首次>k的时候进行贡献统计, 那么累计的代价是k^2(每个点和其它点最多发生一次计算,而直接对半就是k^2), 产生>k的个数是O(N/K)次, N/K * K ^2 = NK
- 如果一个多于k,一个少于k, 那么每个代价为small * k, 而所有small的和O(N),(因为每次发生后small的点讲不再是这种small x large的情况,所以每个点最多属于一次small),所以总的是O(NK)
因此总的复杂度是O(NK).
这题解上的没看懂,看的snuke的博客看懂了, 感谢snuke的博客和google翻译
代码
https://atcoder.jp/contests/abc235/submissions/34665160
1 |
|
总结
G
组合数, 虽然看起来 = sum binom(i,0..min(a,i)), 是上面不动,下面动, 但实际上把下面提出来,以及定义无效的binom=0, 就变成了只于上面有关的binom和了,且可递推
有道理, 在公式上推半天,不如在二维平面看binom 推得很显然
Ex
好消息是 竟然 想了主要的内容,虽然可能这评分不太准,
但是树上dp不了解这个复杂度
又学了一下树上 dp, 做子节点乘积的复杂度分析.., 感觉之前有树上启发式合并,是按照重轻链来分类讨论,这个是按照子树节点数的重轻来讨论
虽然日常手写dsu,也是学了一下atcoder的dsu库