SDSC2021
有很多东西还没有写。。。
zyb七道ioi两道imo,以及lxl的题看起来非常不可补!!!
Day1
测试
\(T1\)
给一个 \(m\) 次的多项式 \(f(x)\) ,令
\(\begin{cases}a_0=a\\a_n=a_{n-1}+f(n)\times a_{\left\lfloor\frac{n+b}{c}\right\rfloor}\end{cases}\)
求 \(a_n\) 对 \(1004535809\) 取模
\(n\le 10^{18},m\le 20\)
PS:zyb不让用lld!!!
\(T2\)
题意:给一张图,每个点的权值 \(w\in\{1,2,3\}\) ,然后对于所有为 \(1\) 的点,选一些特殊点,使得去掉所有 \(2\) 点或者去掉所有 \(3\) 点之后,任何一个 \(1\) 点所在的连通块内都至少有一个特殊点,最小化特殊点的数量,输出方案,对于 \(2,3\) 求同样的东西。 \(n\le10^5,m\le 2\times 10^5\)
\(sol\) :把所有 \(2\) 点删掉会形成若干连通块记作 \(p_1,p_2,p_3...p_k\) ,把所有 \(3\) 点删掉后形成的若干连通块 \(q_1,q_2,q_3...q_l\) ,然后考虑建一个二分图,然后左边是 \(k\) 个点,右边是 \(l\) 个点,两个点之间连边当且仅当有点同时在这两个连通块里,然后问题就变成了最小边覆盖,总点数-最大匹配,构造方案的话,就是先把最大匹配的边都搞了,然后剩下每个点随便找条边就好了/kk
PS:俺考场上yy了一个贪心,然后发现大样例过不去,于是让它按随机顺序遍历每个点,多跑几遍获得了70pts
\(T3\)
题意:交互题,每次询问两个点之间的距离,次数不超过 \(m\) 次,让你构造这棵树。 \(n\le 10^5,m\le 5\times 10^6\)
PS:tyy二轮给过一个 \(n^2\) 的题,然后我就硬搞过来了,然后zyb不讲武德和暴力一个分,但还有点良心给了45
讲课
主要讲题答,讲了模拟退火,原理是最优解附近通常也很优,为了避免陷入局部最优解,需要一定概率跑出去。然后控制一个温度,温度越高就越可以跳出去,过程中不断降温。
然后讲了各种模拟退火和各种造计算机题,没得写。。。
交互
\(T1\) :两个 \(int\) 范围内的数 \(x,y\) ,每次询问可以给两个数 \(z,w\) ,然后会告诉你 \(x\oplus z\) 与 \(y\oplus w\) 的大小,确定 \(x,y\) 。询问次数 \(65\) 。
\(sol\) :首先都异或 \(0\) 确定两个数哪个大,不妨设 \(x<y\) ,那么从第一位开始考虑,先对 \(x\) 第一位取反,再对 \(y\) 第一位取反。两次的结果代表的数字和把这一位都清零之后剩下的数的大小如下。
\(<,<:0,1,x<y\)
\(<,>:1,1,x<y\)
\(>,<:0,0,x<y\)
\(>,>,0,1,x>y\)
\(T2\) :二分,询问次数卡的非常紧,如果你最后要多问一次那你就无了。
\(sol\) :不会,好像是从下往上构建决策树然后随机区间什么的我不会。
\(T3\) :你有 \(n\) 台机器,有好的和坏的,然后好的一定比坏的多,好机器说话一定是真的,坏机器说话不能判断真假,然后你最多 \(2n\) 次问机器 \(i\) ,问他机器 \(j\) 是好的还是坏的。最后判断所有机器的好坏。
\(sol\) :做一个栈,栈里面元素的类型都一样。然后如果栈目前是空就把这台机器扔进去,否则让它和栈顶互问,如果都说对方是好的,那么这两要么都好或者都坏,直接丢进栈就好,否则一定一个好一个坏,那么两个都扔掉,因为好的比坏的多,所以最后栈里面剩下的一定是好机器。然后你过程中那个并查集啥的维护一下什么就好了。
关于这个题zyb提了另外一个题,这个题据zyb研究可以出成交互,一堆数,众数出现次数大于 \(\dfrac{n}{2}\) ,要求你空间 \(\Theta(1)\) 求出众数。类似于这题,两个变量,一个记录目前的众数,另一个记录出现次数,如果目前出现次数为零就把这个数当众数,否则如果这个数和众数一样那么出现次数加一,出现次数减一,因为众数出现次数大于 \(\dfrac{n}{2}\) ,那么最后一定是众数留下。
\(T4\) :竞赛图,每次可以询问一个点与另一个点之间边的方向,然后求这个图中的一条长度为 \(n\) 的链。 \(n\le 10^3,m\le 10^4\)
\(sol\) :考虑增量,如果 \(n\) 指向链头那么做完了,如果链尾指向 \(n\) 那么做完了,否则中间一定有个位置 \(x\) 使得 \(x\rightarrow n,n\rightarrow x+1\) ,这个可以二分,以前紫书上做到过,虽然它没有什么单调性。。。考虑最后一定是一堆指着 \(n\) 的,所以有解是肯定的。那么你二分一个位置,如果它也指着你后面也指着你,那么它肯定在一堆指着你的区间里面,那么前面到这里肯定有个位置复合,如果在一堆被指着的区间里面,那么后面肯定有个位置符合。
\(T5\) :一棵二叉查找树的权值是点的编号,然后你 \(2n\) 次询问一个点是否是另一个点的祖先,让你确定这棵二叉查找树
\(sol\) :模拟建一棵笛卡尔树即可。
通信
\(T1\) :给一棵 \(n\le 70\) 个点的树,然后程序 \(A\) 要输出一个 \(128\) 位的 \(01\) 串,\(B\) 要根据这个串把树复原出来。
\(sol\) :因为一棵树 \(dfs\) 的时候,进入加一个左括号,出来加一个右括号,除了根以外都这样做,那么形成的 \(2n-2\) 的括号序列是唯一的,然后卡特兰数 \(C(69)\) 恰好比 \(2^{128}\) 小点,然后你只需要求字典序第 \(k\) 大的括号序列,\(oiwiki\) 上有,这个过程可逆。
\(T2\) :给一个 \(10^{18}\) 以内的非负整数,然后你输出一棵不超过 \(100\) 个结点的树,然后根据这棵树复原这个非负整数。
\(sol\) :考虑一条链上挂不超过 \(2\) 个点总共有 \(4\) 种情况,那么你每种情况代表一个树,然后就是 \(4^{30}\) 左右的数都可以表示,多用几个点可以表示更大的,tyy有一个组合数的东西貌似可以把这个数据范围翻倍但我不会。
Day2
测试
\(T1\)
题意 :问有多少个排列,满足每个数在 \(1-a_i\) 或者 \(a_i-n\) (题目会告诉你),\(n\le 5\times 10^3\)
\(sol\) :\(dp\)
\(T2\)
题意 :给一棵树,有 \(m\) 个物品,每个物品经过一条边有 \(p_i\) 的概率消失,随机选取一个起点和一个终点,问从起点花 \(a_i\) 元买入,花 \(b_i\) 的钱在终点卖出去,如果中间消失就亏钱了,问对于每个物品期望赚多少钱。\(n,m\le 10^5\)
\(sol\) :多点求值+点分治
\(T3\)
题意 : 通信题, \(A\) 输入一个 \(n\) 位 \(01\) 串,输出一个 \(m\) 位的 \(01\) 串,其中有 \(k\) 位是指定好的,\(B\) 只知道 \(m\) 位的 \(01\) 串,问一开始的 \(n\) 位 \(01\) 串是什么样。 \(n\le 10^3,n+k+50\le m\)
\(sol\) :
讲课
构造
\(T1\) :构造一个长 \(2^n\) 的首尾相接的 \(01\) 串,使得所有相邻的 \(n\) 位恰好组成 \(2^n\) 种不同的 \(n\) 位 \(01\) 串。
\(sol\) :欧拉回路
\(T2\) :
后来整了一堆ioi和imo题,有空再搞
Day3
测试
讲课
\(CF150E\) :写过这个题,当时有线段树的三 \(\log\) 做法,还有单调队列排序的二 \(\log\) 做法,但都是基于点分治的,lxl毒瘤给出了不用淀粉质的一 \(\log\) 做法。首先二分是肯定的,然后就变成了线性求一条长度最大的链,然后长链剖分按 \(\log(n)\) 分块,对块动态建 \(st\) 表,然后不会了。
\(CF793F\) :考虑扫描线扫右边界,因为是维护 \(\max\) 一类的东西所以向右扫看起来才比较像话。然后就维护 \(f_i\) 表示从 \(i\) 开始爬的答案,对于一个右边界,因为右边界相互不同所以有唯一的对应的左边界 \(l\) ,然后就变成了对 \(i\le l,f_i>=l\) 修改 \(f_i\) 为 \(r\) ,然后这是个经典吉老师线段树。
\(CF536E\) :考虑 \((u,v,l)\) 有三个自由度,前两个是等价的,然后你发现如果每条边的权值一直在变那你好像很难做,所以我们考虑离线扫 \(l\) ,然后每条边的权值只会变化一次,这个时候你树剖一下,变化就变成了单点修改,然后查询的时候你只需要每个区间内部的答案,以及跨区间的答案,你只需要知道左区间右边有多少个连续的 \(1\) ,右区间左边有多少个连续的 \(1\) 就好了。
\(CF1476G\) :
\(CF1109F\) :
\(CF1446F\) :
Day4
Day5
测试
讲课
\(CF360E\) :首先如果可行,那么必然存在一种方案,使得边权不是 \(l_i\) 就是 \(r_i\) ,这个其实是很套路的,因为找到 \(s_1\) 到 \(t\) 的最短路径,如果这条边在这条最短路上那么取 \(l_i\) ,否则取 \(r_i\) 。
正解是这样的:初始令所有边的边权为 \(r_i\) ,然后如果存在一条边权为 \(r_i\) 的边 \((u,v)\) 使得 \(dis_{s_1,u}<dis_{s_2,u},\) 那么就把它的边权变成 \(l_i\) 。最多跑 \(k\) 次 \(dijkstra\) 把所有能改的边都改了。
考虑这条边是否在目前两个起点的最短路径上,如果都在,那么改不改无所谓。
如果只在 \(s_1\) 上,那么改了肯定更好,这个时候如果改这条边有意义(指改了之后有可能会有解),那么 \(dis1_u<dis2_u\) ,如果不满足,\(s_2\) 的路径最差情况下也可以经过这条边,然后把 \(s_1\) 吊起来锤,所这时候改不改是没有讨论意义的。
如果只在 \(s_2\) 上,那么同样的道理,如果 \(dis1_u<dis2_u\) ,那么改不改无所谓改了就是了。
如果都不在,那么考虑改了之后的结果,如果两条路径都不会变或者都变那么无所谓,因为 \(dis1_u<dis2_u\)。如果变,如果先变了 \(s_2\) 的,那么因为 \(s_1\) 没变过来所以肯定要比 \(s_2\) 优,改不改都可以,如果先变了 \(s_1\) 的,那么说明优化了 \(s_1\) 肯定更有可能。
所以变了肯定不会变劣,变它就是了。
\(CF772E\) :考虑增量,维护虚树,那么因为这棵树的特性,所有点构成的虚树就应该是最终的答案。然后我们动态暴力点分治,我们查这个点和左右儿子中任意一个叶子的答案,然后我们就可以确定出是在左儿子还是右儿子,然后边界条件是如果到了叶子,或者到了这一次增量一个访问过的重心,那么新建结点。
\(CF843E\) :
\(CF1209H\)
\(CF1270I\)
\(CF1292F\)