日记
以我的码力,一个晚自习改出三道 NOIP+ 还是太难了点。
能不看 std 写出来还能过就很不错了,就是实现太优秀了点
赛时发现是容斥。也就发现是容斥了
设 dpi,j 表示前 i 个家族里钦定有 j 个投了自己家。转移类似背包:dpi,j=∑k=0min(j,leni)dpi−1,j−k×gk。其中 gk 是在枚举每个家族时分别处理的,表示当前家族如果有 k 个投了自己人的方案数。leni 表示家族 i 的大小,
考虑如何求 gk。设 fi,j 表示当前家族前 i 个人有 j 票投了自己人。那么有 gk=flen,j,这下只用求 fi,j 了。有 fi,j=∑k=0min(j,ci)fi−1,j−k⋅(ci−k)!1(klen−j+k)。
然后容斥一下:ans=∑i=0n(−1)i×dpm,i×(n−i)!
我们对每个 ai 分别考虑它所需的步数,那么题意就变成了 ai 所需的步数的最大值最小,直接开始二分。
考虑如何 chk
二分出来的 mid。要使 a′ 单调不降,ai′ 必须 ai−1′。设当前 ai′=lst。暴力枚举 lst,lst+1,lst+2,…。看看 ai 能不能在 mid 次变成 lst+x。发现每次要么成功,要么 lst+1,而 lst>m 的时候又非法了,所以这种方法的复杂度是 O((n+m)×检查的复杂度。
发现 n≤106,所以不能双 log。而我们的二分已经用了一个 log,所以我们的检查复杂度必须是 O(1) 的。发现 b 可以建模成一个基环内向树。我们预处理每个点:所在联通块的编号;树根编号;深度;设我们要求 s→t 的距离:
- 在同一联通块
- t 在环上
距离为 depv−1+(rnkt−rnkroots+len)modlen。
- t 是 s 的祖先(需要奇技淫巧)
距离为 deps−depv
- t 不是 s 的祖先
return inf;
- 不在同一联通块
return inf;
然后这题就做完了。复杂度 O((n+m)logm)。
其实 T2 不算太难。就是那个 O(n+m) 的判断有点沟槽。
码力还得再练,不过是比之前强了。