CodeChef November Challenge 2013 题解

最后得分是8.007分……比赛结束前3天还是并列rank5,结束前1天看了一下发现到rank8了……结束了一看到rank15了……简直吓尿了,会写计算几何/神数据结构的人咋这么多……


下面题目按通过人数排序……由于CC这次有中文题面而且可以看到所有代码,就不讲题意也不贴代码了……


JOHNY:略。

MCHAIRS:答案就是2^n-1。

SDSQUARE:预处理出所有合法的数,然后二分确定给定区间内有多少个数。事实上合法的数没几个,都不需要二分。

SPOTWO:n转成二进制,对(mod-1)取模,然后快速幂。


PRETNUM:

这题有点意思……

不难得出合法的数要么是质数,要么是质数的(质数-1)次幂……

既然题目保证R-L<=100w,那么肯定是有用的,肯定只能枚举每个数……但是直接判断是会TLE的……

最开始的想法是这样的,先判断是不是2、3、5、7、11的质数-1次幂,如果不是那么次数肯定不超过11,枚举之后二分判断……最后再用Miller-Rabin加快速乘法判断一下是不是质数就好了……

写完了随便测了个数据,发现5s内跑不出来……

然后事实证明只做Miller-Rabin都会TLE……

进一步又证明去掉快速乘法直接Miller-Rabin都会TLE……

……于是这题就被放了一两天……后来zhx说可以考虑求所有不合法的数的个数,于是就有了下面这个算法:

先求出1~sqrt(n)的所有质数,然后用筛法筛掉l~r内的所有合数(我不会说开始想用容斥各种搞),之后再把l~r内质数的(质数-1)次幂的数给加回来就得到答案了……


之所以这题写这么长一段,就是为了记住不要想多……


SEAVEC:

随便随机一个顺序能选就选可以得0.007分,就是我的做法……

令d[i]为max{a[i][j]/b[j]},然后按d升序或者降序选就能的0.036分……

如果先随便加一些,然后不断随机选择一个已经加入的和一个尚未加入的,判断是否能交换两者,如果交换了更优就交换,可以得到0.4几分……

……………………等等……写到这里的时候大家的分数都变了……怎么回事……好惊悚……

然后满分的(至少变之前满分……)也是类似的做法,但是还有强制的删除或者插入(前提是合法),于是遇到正解的可能性更大……

说白了都是乱搞做法……只是看是不是足够高级……而且不管是哪个写起来都有点麻烦……


CHEFGM:

博弈题。麻烦在于双方的决策是不同的,所以不能用SG。于是上网各种搜,搜到了这篇论文:方展鹏《浅谈如何解决不平等博弈问题》……虽然看不懂证明,但是照着结论敲就过了……

事实上,这题就是裸的Red-Blue Hackenbush问题……这类不平等博弈问题的通用解法是用surreal number(中文:超现实数)……虽然我也不知道咋弄的


GERALD2:

要论难度这题绝对比下面一题难……不过这题就是QTREE4的化简……于是直接用QTREE4的做法就行了……

由于我没写过QTREE4,所以还是讲一下做法……

首先做一遍点分治,对于分治出的每一棵子树的根,维护一个堆,每个元素是其所有儿子的子树中的到根的距离的最大值。而对于每个儿子再维护一个堆,维护子树内所有点到根的距离。由于树分治只会递归O(logn)层,所以只有O(nlogn)个堆。

对于每个修改,定位到其每层的子树。如果是黑改白,就往对应子树的堆中插入,如果成为了子树中的最大值,就往根的堆中插入。有重复的元素没关系,反正一次操作最多插入O(logn)个节点。如果白改黑,直接打个标记。每次访问一个堆时,如果堆顶是黑色的节点,或者堆顶节点不是所在子树内的最大值,那么先弹出来,并重复判断。

对于每个查询,同样定位到其每层的子树。考虑一棵子树,如果查询的点是根,那么用根的堆顶更新答案;不然就用自己到根的距离,加上根的堆中一个和自己不在同一个子树内的点的距离更新答案。这里有两个特殊情况,一是堆中没有元素,那么就直接用到根的距离更新。二是堆顶元素和自己在同一棵子树内,那么先取出堆顶元素,然后弹出所有不合法元素之后的堆顶就是答案了。之后再插回去就好了。

……感觉好像没说清楚。去搜QTREE4的题解吧,反正网上到处都有……似乎大多数人是用边分治做的,不过由于我没写过边分治,就用zhx的点分治的办法做了……


MONOPLOY:

一直以为题目名字叫MONOPOLY……

观察一下可以发现,题目中的树和动态树十分相似……一个点的代价就是往根走经过的虚边条数,而O操作就是expose一个点……

那么我们就写一棵动态树。由于动态树的均摊复杂度是O(nlogn),所以所有改成实边的虚边条数应该也是O(nlogn)的(还是O(n)的?有谁知道……)而实边可以视为边权为0,虚边视为边权为1,修改一条边的边权只对子树有影响,于是用一棵线段树维护DFS序,查询子树的问题也就解决了。


QPOINT:

对这个大家都会写计算几何的世界绝望了

如果可以离线,那么可以用扫描线+平衡树各种搞……由于强制在线,那么有两种做法,一是把平衡树可持久化……zhx似乎写了这个但可惜没调出来……二是直接上点定位……不过鉴于我两者都不会写,也就没啥好说的了……

你可能感兴趣的:(CodeChef)