纪中国庆集训 简要题解

来源:互联网 发布:linux 文件上传权限 编辑:程序博客网 时间:2024/06/01 09:06

QaQ主要是因为题目太难写不动blog一直在调程序……所以只好先口胡一波题解
A组10/5
T1:
题意 找k次连续的”23”,每次若”2”的位置为奇数则将其变为”22”,反之为”23”,求最后串变成了什么
题解 我们会发现实际上只有两种循环节”223”和”233”,且要求开头再奇数位,其他的消掉之后不会再产生太多……于是只要不断维护下一个就好了 可以用一个指针直接维护,看情况前移后移,可以发现还是线性的。也可以维护一个链表维护下有序序列,不过太麻烦了?
T3:

A组10/6
T1:
题意 设f(i)表示不大于i的数中与i互质的数的平均数,求Ri=Lf(i)k 模某经典质数
题解 首先由于(x,y)=1(x,xy)=1,那么我们可以发现其实f(i)=i
于是这题就变成自然数幂和的裸题辣 有好多经典做法 某次CF的EduRound还出过一次E(好像是10左右吧)
由于我们可以证明自然数幂和是有k+1次的通项的,所以我们只要爆算到k+2的自然数幂和然后用拉格朗日插值就可以搞出这题了。本质上来说,就是高斯消元爆解,但是拉格朗日插值法无疑更加简单。
既然是插值法,那就是构造下函数使得函数过k+2个点,那么我们只要考虑对于x=i,让除了包含当前应该有的yi外的项都来一个(xi)消掉,然后有yi的那一项只需要让系数为1,然后考虑到其他xi的情况只需要除掉k+2j=1,ji(ji)就好了 然后显然是对的。
我用的其实是斯特林数 懒得讲辣
这题还可以用差分表搞出来 等我看完FuLan大爷的博客再来填坑……

T3:
题意:先给出一些字符串 然后动态加进去字符串和查询一些字符串的公共后缀长度
题解:竟然没看出有Trie的动态做法我是不是傻了……
(第一眼:离线把串拼在一起!SA!
过了一会:诶好像还能Hash?算了不管了
考试后:哇哇哇还能Trie动态做……)
先不考虑动态加串 倒着加字符串然后丢Trie里 乱跑LCA
然后再考虑加了串之后怎么继续维护LCA
我们发现给新加的点稍微维护下向上倍增的数组就好了 于是几乎不用加代码
当然离线之后树剖和Tarjan都行(树剖LCA代码好短啊)
顺便%一发某个Splay维护DFS序列的Dalao?
A组 10/7
T1:
题意 给出一个DAG,开头结尾外点数每层为k,可以将相邻两层之间的边翻过来交换连接,问使得最终路径条数为偶数的方案数 模某经典质数
题解 状压DP,因为只需考虑奇偶性,所以用01考虑k10所以直接压进去,另外记下当前搞的是从上往下第几个,然后考虑对一个状态把可产生的状态先用二进制打出来奇偶性,转移的时候直接做,然后用lowbit优化下转移(只转移为1的),先翻过来和不翻的都做一遍就好了

T2:
题意 给出n+1个集合(n是偶数),每个集合有2n个数,用一种神奇的方式给出每个数的存在性(64进制???),然后要求找到一对集合使得交大小不小于n2
(吐槽) 暴力出奇迹!暴力踩标程!(误)@Snakes用标程给的方法130+ms然后暴力1ms!
我是用bitset硬上的因为比较好写,然后现在还是最短代码 另外这题原本有一个”NO Solution”然而事实证明不存在这种情况(所以没用?)
题解 反正暴力可过,我们就只来解释下为何暴力可过吧 正解其实是随机n对判断……不过好像比较慢
我们先定义一个期望,为两两集合交大小的平均(就是随机选两个集合交的大小),同时还是按照二进制我们设一个ci,表示第i位上有几个是1,因为每个都是大小为n的子集,于是2ni=1ci=n(n+1)
然后我们发现对于其中第i位选的总数是C(n1,2)=O(n2),能够恰好交起来方案数C(ci,2)=O(c2i),那么这里总的期望就是2ni=1C(ci,2)C(n1,2)=O(2ni=1c2in2)。由均值不等式中QnAn,即

2ni=1c2in2ni=1cin=O(n)

两边平方之后再除就可以得到那个期望就是O(n)的了(实际上,猜一下由对称性都知道是等的时候取极值)
那么在这里期望就有O(n)个了,精确值应该是n12,如果平均值到n,那就显然有满足条件的。由上面的推理我们已经得出不会没解了,所以这里需要大一个常数,如果要补上这个常数需要至少O(n)个集合之间有n2规模的交,也就是说,这样的对数不只有,还挺多的……
所以完全可以暴力做(暴力还挺快的)。
T3:
题意 在一棵树上选最少的点使得每个选定的点能在经过k条边后到达的所有点中选出一个大小为s的点集,使得所有点集的并集为整棵树的点
题解 强行贪心一波 我们会发现我们应该尽可能用完这k的长度,因为可以涉及到的点是最多的 同时我们应该选尽量深的点 因为选其他的不会更劣
然后我们设F(x,k)表示x下面距离为k的多余覆盖点的个数(就是子树里面选定的点往上还可以延伸的点的个数),G(x,k)表示x下面距离为k的还需要被覆盖的点的个数。接着我们先考虑用F(son(x),k1)转移到F(x,k)G一样),接着考虑下二者间的差距,F(x,k)G(x,kk)互相填一下,然后利用除以s的公式直接求好要多多少点,最后再把答案更新一下就好了
这样说好像不太清楚,不如看程序:http://paste.ubuntu.com/25692676/
剩下的先留着坑

原创粉丝点击