愚人节CDACMFinal
这个啊,愚人节的ACM之赛,其实还是很有意思的。之前因为星期天不能休息还怨声载道,但真的打起来了就是觉得特别有意思。
我们队,最开始乱搞电脑,cmd都没有办法调用了,霎时间十分慌张(而且我过于慌张忘了带杯子,最后喝了ZJC的Water……)。最后也没有用vim,全程dev。过了好一会儿题才发下来,直接把题拆了,先把题读了,为的是能够准确把握比赛进程。之后发现AK之队火速AC了G题,G题的树上版本在前一天才考过,利用了随机树深度log的性质。但G题在序列上,于是直接就水掉了(其实并没有,因为忘了开long long)。之后,裘说D也是水题(程鑫潘星霖队最先A),但我按照她的题意写了出来却完全错误,和ZJC商量了好久觉得我的做法没有问题再验证数据发现根本不是如此,对此事我确实很愤怒,一个人应变应当镇定而不是一味的抱怨,后来ZJC又读了好久的题目才读懂,一下子就AC了。然后,ZJC从隔壁队听来J是二分答案,觉得想出来了于是上机,敲了一个多小时才发现自己是错的不能二分答案(其实是可以的,YYF隔壁队AK队都是用的二分答案……)。再之后,我们惊奇地发现高新高一有个队A了F题,裘说F是个DP(裘把F也读错了),我没有想太多,她完全敲完交上去才不对(这中间AK之队已经获得了全场的掌声走了人),想得越来越复杂还有一些“执迷不悟”,又一次“坑”了队友。这个时候,ZJC说F一定可以乱搞,裘像是个“卫道士”,在我和ZJC的“夹逼”之下开始敲,第一发TLE,改小了乱搞范围就AC了(此时已经封榜)。再让裘读K,这一回终于没有问题,最大权闭合子图的裸题就AC了。最后一共五道题目,DGJ是签到题(然而因为某些让人很愤怒的原因花了4个小时),F题DP没有写成(也费了不少时间)却乱搞轻松过了,K题Dinic我也可以一A。
在封榜之前(最后一个小时封榜,各种状态都无法感知)AC了签到题,拿到了3个气球,然而最后两道题都没有了气球(AK队一共11个气球呢……)。王嵩乔队AC了F题后,十分鼓舞却发现没有气球(因为已经封榜了),竟还去找了组委会。D题YYF队也没有读懂,竟然找HY跨房间问我们队……
要总结么?我觉得,大概就是“临危不能乱”了。但题目的总结,也应该是很有趣的。考试结束之后,我去AK队的电脑上copy了AC代码,好好研究了一番,大有所悟。
A:多队AC题。给出一个S=2e5的矩阵,询问其所有子矩阵之和的k次方的sigma,不妨设上下长N左右长M且N≤M即N≤sqrt(S)。我当时很傻,直接枚举右边界,左边界上边界下边界都没有定下来,就有3个sigma,4个角的差分十分经典,但加上4次方一共就有35项,虽然每一项都可以O(N*M)来进行维护。正解的做法是:枚举上下边界,将左右边界放入sigma,这就只是2项的4次方了非常好写,复杂度O(N2*M)。
B:多队AC题。给出一个2e5的序列,进行2e5次询问,每次给出若干个位置这些位置的数可以任意调换顺序并询问序列最小逆序对数。如果真的稍微想一想,就可以发现一定是从小到大塞入序列的。于是现在问题变成了若干个位置进行排序询问序列的逆序对数,这个可以使用主席树+树状数组解决。是这样计算的:先预处理出主席树并算出整个序列的逆序对数,针对每组询问先减去给定位置与数列其他数的逆序对数,因为给定位置之间的逆序对数减了两次于是需要使用树状数组把给定位置间的逆序对数减去,这样就得到了序列去掉了给定数后的逆序对数,之后再把每个数加进去,先把新位置对应的前后逆序对数加上,但中间有一些是跟原来的数形成的,于是再从头到尾从尾到头将原位置的数加入树状数组并减去新位置的数跟原位置的数形成的逆序对数,就得到了答案。
C:AK队独家。1e5的带边权树,询问树上最大k匹配,一个匹配就是选择一条边并获得其边权但不能选到重复的点。暴力DP大概是O(nk2)的,费用流是O(SPFA*nk)的,虽然显然可以用费用流但我还是想了好久,最后问森才知道奇偶深度二分图的做法。看完WXH的代码后,一时间想到了tree(无向图恰k条白边的最小生成树,其实确实是相同做法)。但不理解正确性,于是去问WXH,终于明白正确性。我们可以画出图像,(i,ans[i])表示流量为i时最大费用为ans[i],考虑费用流一定是每次只增加1流量而且增加费用递减并可能变成负的,所以该图像是上凸的(x坐标的值域=[1,max flow])。我们现在要算出(k,ans[k])的ans[k],直接算很困难。但是该图像是上凸的,如果用斜率为x的直线去切凸包,那么切点就是ans[i]-i*x最大的位置。把-x带入边权,就很容易能够算出x对应的切点位置以及ans[i]-i*x的值(因为树上最大权匹配很好做)。根据斜率对应的切点位置二分最终的斜率范围(因为斜率单调变化切点的位置也单调变化),最后就能够得到让k作为切点的斜率ansx,所算出的ans[i]-i*ansx的最大值加上k*ansx就可以得到答案了。之前我一直不了解tree的正确性,将这段话带入就很清楚了。此外,如果树是一条链,那么可以使用堆进行可后悔贪心,但我记得曾经有人说过可以如是二分而且可以拓展到树上,不知道是不是梦境的幻象。
D:签到题。“坑”队,点与球所有切线切点的中心,直接射影定理水掉。
E:AK队独家。给一个2e5的串,2e5次询问,每次询问一个子串在原串中所有出现位置的并。肯定是SAM的right集合,子串也可以倍增找到。但是并没有深入往下想,只想着某些位置可以被很多很多串覆盖,只想着知道right集合和子串长也不能暴力做。但这其实是启发式合并+线段树,线段树维护right集合中相邻点的位置差,串太长前一个串的后半部分就会被后一个串覆盖而且不会再有多,要计算长度并就很方便了。
F:乱搞AC题。“坑”队,给出10000个1e9以内的数,再给出100~109每一位的限界值,询问是否所有子集之和的每一位都≤该位的限界值。一共有210000个子集,但是枚举几百万个就可以过,因为数据真的很难造那就不如直接随……验证第10i次方位是否合法,假设该位的限界值为ai,对每个数%10i+1即不考虑更高位的数字,最开始的时候只要有数为[ai*10i,10i+1)就会NO,现在加入一个数ci那么之后如果有数为[ai*10i-ci,10i+1-ci)就会NO,扩展后即加入ci后每个区间向左移动ci,但这样区间数是否会多到无法接受呢?并不会。因为,每个区间的长度至少是总值域[0,10i+1)的十分之一,于是合并之后总的区间数也不会超过10。此外还需要注意处理区间变负,因为是%10i+1所以并没有任何问题。实在是太强啦!
G:签到题。给一个1e4的排列,询问所有[l,r]区间的l*r*中位数之和。可以枚举中位数再向两边延伸(因为是排列奇数就直接保障了)。
H:多队AC题。n≤40盏灯和m≤40个开关,每个开关可以控制一些灯,询问2m种方案每个方案亮灯数的k次方之和。这个东西很容易想到异或,相当于是有m个n位二进制数,询问每个子集异或和中1的个数的k次方之和。它十分充分地利用到了线性基的性质,我们可以把m个数放进这大小为n的n位二进制数组成的线性基中,设秩数为fre自由元个数为m-fre,那么求出线性基能够xor出哪些数将其1个数的k次方加入答案,最后因为线性基能够xor的所有数都出现了2m-fre次所以需要乘上这么多。当fre≤25的时候,线性基能够xor出2fre个数直接暴力即可。当fre>25的时候,线性基中的空秩只有不到15个,可以考虑把这个当成状态压入DP中。DP的时候,先将线性基标准化(即如果2i这个秩非空则其他非空秩的2i位为0),然后处理出每个非空秩包含哪些空秩的位,转移的时候枚举所有非空秩,用f[i][S]表示已经选择i个非空秩且这些非空秩异或后包含空秩集合S的方案数。最后统计的时候,f[i][S]就表示非空秩位一共有i个而空秩的位上包含S这个集合,就是说(S的1的个数+i)个1的数贡献了f[i][S]个,复杂度O(225/40*40*215)。实在是太强啦!
I:AK队独家。正解还不会。
J:签到题。“坑”队,题意不想再说,可以直接贪心,二分答案也没有任何问题。主要的思想是两个选择在圆上的高度相等,可以从上往下做。ZJC被坑了很久,因为他自时至终都把问题放在了环上,我“想不出来”是因为我破了环成了链(无法说服ZJC)。
K:AC题。题意不想再说,最大权闭合子图裸题,题目怎么说我就怎么做,2000以内的质数之和很小。