浙江农林大学
第二十二届程序设计竞赛
感谢各位捧场!
瓜瓜打游戏(EASY)
考虑计数 DP,设 g(i,j) 是拿到了通过 i 关后拿到了 j 个徽章的路径数,其可以由
- 通过 i−1 关拿到了 j−1 个徽章,在第 i 关拿了徽章有 ai 种可能。
- 通过 i−1 关拿到了 j 个徽章,在第 i 关没拿徽章只有 1 种可能。
转移到。即得转移式
g(i,j)=g(i−1,j)+ai×g(i−1,j−1)
边界情况是 g(0,j)=[j=0]。递推即可。
这里是代码
瓜瓜打游戏(HARD)
我的方法十分的繁琐(离谱),期待有 dalao 给出更优的方法。
若我们记 fi(x) 是 g(i,j) 的 OGF (普通生成函数),可以发现
fi(x)=fi−1(x)(aix+1)
故 EASY 的答案可以表示为
f(x)=i=1∏n(aix+1)
而 HARD 中指定 f(x) 的只有最高项系数和最低项系数不为 0。即有如下形式
(i=1∏nai)xn+1≡i=1∏n(aix+1)modp
因为 p 是质数,因此 bi=−ai−1 总是可逆的,从而上式可以被重新写为
h(x)≡xn−c≡i=1∏n(x−bi)modp
这个形式指引我们从根的角度思考问题。若 ai 中有重复,那么 h(x) 会存在重根 x=b′,求导后仍是零点 h′(b′)≡0;但是和上式左边 h′(x)≡nxn−1 矛盾。故 ai 中没有相同的数。
接下来便是在 Fp 中讨论 c 的可分解问题,即 c 应是 n 次剩余。因为 p 是质数,故 p 一定存在原根 g,故我们总可以取离散对数 c=gloggc。
若 bin≡bin≡c,那么
nloggbi≡nloggbj≡loggcmod(p−1)
不难通过同余方程的知识,计算得 c 这样的 n 次剩余有 gcd(p−1,n)p−1,其中每个 c 对应于 gcd(p−1,n) 个 bi。若我们需要 n 个解,那么有 n=gcd(p−1,n),即 n∣p−1。
综上所述,当 n∣p−1 时,考虑 bi 的排列,有 n!×np−1=(n−1)!(p−1) 个解;当 n∤p−1 时,有 0 个解。
这里是代码
瓜瓜喜欢做 A+B
不难发现,无论选择哪个点涂色,都会覆盖 n+m−1个格子,而且必然会覆盖上一轮染色的部分点。
由于每一次染色所用的颜色都各不相同,那么最后一次染色的颜色面积最大。
故输出最后一次所用的颜色编号和 n+m−1 即可。
这里是代码
瓜瓜轰炸机
设一个格子的坐标是 (x,y),当 x+y 是奇数时,我们称这个格子是奇性的;反之,若 x+y 是偶数时,称为偶性的。
注意到当选择一个格子轰炸时,此处的敌人一定会逃向奇偶性不同的格子。所以当我们轰炸了所有奇性的格子时,就可以保证剩下所有敌人位于偶性的格子内;反之同理,轰炸偶性格子后敌人会跑到奇性格子里。
因此按照此规律轮番轰炸所有偶性格子与奇性格子即可。需特殊注意只有一个格子的情况。
这里是代码
瓜瓜不想上电工课
要让电路中的总电阻尽可能小,那就应当优先翻转 ai−bi 大的灯泡。令 ci=ai−bi 并将其降序排序,取前 k 个大于 0 的数即可。
这里是代码
周周的猫窝
假若仅考虑猫窝 Ai 和猫窝 Aj,可以发现分割其领地的是中垂线,Ai 拥有的领地是中垂线的一侧,即一个半平面。
考虑所有的猫窝,那么 Ai 的领地应是所有半平面的交集,即所有中垂线围成的区域。
本题数据 n 最大才只有 10 个点,只卡了暴力,任何一种通过几何计算的做法都可以过。
- 做法一:半平面交。
- 做法二:n−1 条中垂线最多有 n2 个交点,若此交点是领地的顶点,则到 Ai 的距离一定最短。大概是 O(n3)。
- 各种瞎搞……
这里是代码(瞎搞的半平面交)
瓜瓜的 01 串
注意到这两种操作先后顺序并不影响答案,即操作具有交换性。
再注意到操作一重复 2 次等于没变,同一位置的操作二重复 2 次也是没变,因此多余的操作一总是可以转换成操作二而不使答案变劣。
故只需考虑 0 次、1 次操作一足矣。再注意当 k⩾cnt1时,因为必需做完 k 次操作,最后剩下 1 的个数是 (k−cnt1)mod2 。
这里是代码
瓜瓜上电工
注意到题目要求测量的接线柱对 (ai,bi),一定会在答案流程中以某种顺序出现。
而在接线柱对的某个排列中,插入额外的中间情况并不会让答案更优。因此枚举接线柱对的全排列即可。
这里是代码
周周的舟舟
本题的关键点是 d 只有 100,并且 x 坐标互不相同,这意味着每个点最多能和 200 个点传导。若一些点的距离小于 d,我们可以把这些点看作一个连通块,最终输出的即是连通块的个数。
这启发我们用并查集解决。当我们离线并排序(离散化)后,对于新加入的点 (xi,yi),连通块的个数先加 1,可以直接找到 xi−d 到 xi+d 范围内的敌人;当连通块发生合并时,连通块的个数减 1。
也可以不离散化,借助 set
和 map
的二分,也可以通过。
这里是代码
策策学长找 py
由于不能走回头路,那么下一个位置一定满足 xi⩽xi+1 且 yi⩽yi+1。
因此可以考虑对 x+y 排序,验证结果满足上述关系即可。
进一步的,可以以 x 为第一关键字,y 为第二关键字排序,判断一下 y 是否是非递减的即可。
这里是代码
瓜瓜选妃
做法一
注意到,若我们修改时考虑二维差分,那么修改是 O(1) 的,求前缀和是 O(nm) 的。
可以对时间二分,总复杂度 O(nmlogt)。
这里是代码(二分1)
这里是代码(二分2)
做法二
考虑用并查集维护。对于每行,用并查集维护右侧第一个未被选择的 MM 在哪里(包括自己);列也同理。当我们需要修改时,就在并查集上边改边跳。
当全部并查集都指向方阵外时,说明全部格子都被选过了。故每个格子最多只会被访问 1 次。
代码:咕咕咕。
周周的泡泡
因为戳破的泡泡必须是连续的,可以考虑二分求解。当我们确定左端点时,随着右端点右移,最终的高度 h 是单调递减的,预处理前缀和后可以二分答案。复杂度 O(nlogn)。
进一步,注意到当左端点右移时,二分的右端点是不会左移的,因此可以用双指针算法,复杂度 O(n)。
这里是代码(二分1)
这里是代码(二分2)
HT 巨巨的磁盘
线段树。对于每个节点 p 维护:左边界最长空闲 Lp、右边界最长空闲 Rp、整体最长空闲 Vp。维护时有一些细节需要注意。
查询空闲 x 时,可以直接在根节点答案是否存在。下面假设答案在节点 p 中:
- 如果当前节点 Lp⩾x,那么节点 p 的左边界即是答案。
- 如果左子节点 V2p⩾x,那么答案存在于左子树中。
- 如果 R2p+L2p+1⩾x,那么答案由两个区间拼成。
- 最后,答案只可能存在于右子树中。
这里是代码(线段树1)
这里是代码(线段树2)