2022/8/30 题目选讲?
据说讲课之后要有一篇 blog ,虽然我觉得没人会看但还是写写罢。
AT2666 [AGC017C] Snuke and Spells
\(n\) 个球排在一起,每个球上有一个数 \(a_i\) 。接下来会进行若干轮删除。设现在还有 \(k\) 个球,则 \(a_i=k\) 的球会被删除。最终可能球不会被删完,你需要求出最少修改几个球上的数后可以让球全部被删完。同时还有 \(m\) 次修改,每次修改第 \(X_i\) 个球的数为 \(Y_i\) ,你需要求出每次修改后上述问题的答案。
\(1\le n,m \le 2\times 10^5\) 。
考虑转化问题。
假设初始时数轴上有 \(n\) 个坐标分别为 \(1\to n\) ,每个坐标上都有一条长为 \(0\) 的绳子。
对于每个 \(a_i=k\) 的球,将 \(k\) 位置上的绳长增加一。
处理完所有的绳子后,将所有绳子平行于 \(X\) 轴向左拉直,如果覆盖了 \([0,n]\) ,说明一定可以通过让所有球消失。如果不能让所有球消失,在 \([0,n]\) 中未被覆盖的总长度即是需要修改颜色的球数,即答案。
对于初始绳子的覆盖情况可以差分,在修改前还原为值数组;修改可以直接操作,判一下是否会导致某个位置空出来即可。
AT2306 [AGC010E] Rearranging
有一个 \(n\) 个数组成的序列 \(a_i\)。高桥君会把整个序列任意排列,然后青木君可以进行任意次操作,每次选择两个相邻的互质的数交换位置。高桥君希望最终序列的字典序尽量小,而青木君希望字典序尽量大。求最终序列。
\(1\le n\le 2000,1\le a_i \le 10^8\) 。
假设先操作的人是 A ,后操作的人是 B 。
考虑 A 操作完的序列如果 \(\gcd(a_i,a_j)\ne 1\) 的话是 \(a_i,a_j\) 的相对位置是不会改变的。则如果 \(i<j\) ,那么在最终序列里一定有 \(a_i\) 在 \(a_j\) 左边。不妨从 \(i\) 向 \(j\) 连一条单向边表示这种关系,最终序列通过拓扑排序即可求出来(不过字典序最大要优先队列)。
考虑 A 的最优策略。将不互质的数连双向边,则 A 的任务即对每条边定向使其变为 DAG 且新图拓扑得到的字典序最小。不妨从从小到大搜每一个位置(如果已经搜过了就不用搜了),对于 \(u\) ,从小到大枚举 \(u\) 的每一个连边的点 \(v\) ,如果 \(v\) 没被遍历过就连边 \((u,v)\) 并继续搜 \(v\) 。
最终拓扑一遍求排列即可。
CF212A Privatization
给定 \(n+m\) 个点 \(k\) 条边的二分图,左边 \(n\) 个点,右面 \(m\) 个点。现在要把每条边标号,标号为 \(1\sim t\) 。求出 对于每个点与之相邻的边中最多的标号与最少标号的数量差 的平均值。
\(n,m,t \le 200, k \le 5000\)。
答案为度数不为 \(t\) 的倍数的点的个数除以 \(n+m\) 。
答案不可能大于这个值(如果度数不能为倍数则 \(\max-\min\) 大于等于 \(1\) )。考虑除掉一些边使得每个点的度数都是 \(t\) 的度数。对于一个度数为\(d_i\) 的点(\(t\mid d_i\)),应该把 \(d_i\) 条边分成 \(\frac{d_i}{t}\) 个块,使得每个块都有 \(t\) 种标号各一个。
考虑加入一条新边 \((u,v)\) 的可能性:在 \(u\) 依然可用的标号中随便选一个没有用的标号,如果 \(v\) 也可用,就直接给 \(v\) 选上;如果 \(u\) 可用的标号 \(v\) 均不可用,则将 \(u\) 的标号进行调整。
具体来说,假设当前 \(u\) 选取的 \(col_1\) ,\(v\) 选取的 \(col_2\) ,则把原来的标号是 \(col_1\) 的换成 \(col_2\) ,如果还冲突则继续调整。简单来说就是类似一个失配重新找配的方式,或者说匈牙利(
CF1019C Sergey's problem
给定一个有重边无自环的有向图,请你找出一个集合 \(Q\) ,使得其中的点两两之间没有连边,且集合中的点可以走不超过两步到达其他所有不在集合中的点。输出任意一组解。
\(1\le n,m\le 10^6\) 。
这题和图论几乎没有关系,有点像构造?我不确定。
设一个数组 \(vit\) 表示最后是否选择这个点。
Step \(1\) : 从小到大遍历所有点,如果这个点并没有被访问过,则将对于和它有边相连且大于 \(i\) 的所有 \(j\) ,\(vit_j\) 标为真。
Step \(2\) : 从大到小扫一遍所有点,如果这个点没有被访问过,则将对于和它有边相连的所有 \(j\) ,\(vit_j\) 标为真。
Step \(3\) : 扫一遍所有点,此时 \(vit_i\) 为假的点即为要选择的点。
证明就不写了,可以感性理解一下(
P7214 [JOISC2020] 治療計画
JOI 村庄有 \(N\) 个房屋,编号为 \(1\) 到 \(N\),每个房屋住有一个村民,第 \(i\) 个房屋居住编号为村民 \(i\)。现在,这 \(N\) 个房屋里的村民全部感染某种病毒,有 \(M\) 个治疗方案被提出,第 \(i\) 个治疗方案描述为,在第 \(T_i\) 天的晚上,编号在 \([L_i,R_i]\) 区间内的村民被治愈。
病毒还会继续传播,在某天早上,如果村民 \(i\) 被感染,那么村民 \(i+1\) 和村民 \(i-1\) 也会被感染,因为病毒威力巨大,所以被治愈的村民有可能再次被感染。
您是 JOI 国的总理,您要选择一些方案使得 JOI 村庄所有村民全部被治愈,一天可以进行很多方案。第 \(i\) 个方案要花费 \(C_i\),求最小花费。
如果无法全部治愈输出-1
。\(1\le N,T_i,C_i \le 10^9,1\le M\le 10^5,1\le L_i,R_i\le N\) 。
建立坐标系,时间作为纵轴、人的编号作为横轴。从左到右考虑每个治疗计划。第一个治疗计划的左端点肯定是 \(1\) ,右端点设为 \(r_1\) 。则 \(r_1+1\) 肯定是被别的治疗计划覆盖的。
这个治疗计划是在第一个之前,设其在 \(T_2\) 覆盖 \([l_2,r_2]\) 的区间,那么当初 \(l_2\) 左侧肯定是没有治疗的,因为 \(l_2\le r_1\) ,\(l_2\) 左侧的人都在等待第一个治疗计划的覆盖。故在 \(l_2+T_1-T_2>r_1+1\) 的时候,就只能覆盖 \([l_2+T_1-T2,r_2]\) 的区间了,如果 \(l_2+T_1-T_2>r_1+1\) ,那么 \(r_1+1\) 就无法覆盖了,故第二个治疗计划必须满足:\(l_2+T_1-T_2\le r_1+1\) 。
相似的,若第二给计划是在第一个之后,由于 \(r_1+1\) 没有治疗,故传染病会向左转移,要想被下一次治疗覆盖,则必须满足:\(l_2-T_1+T_2\le r_1+1\) 。
于是可以将治疗计划看成一个点,满足上述条件,则连一条权值为 \(c_j\) 的边,并将所有 \(l_i=1\) 的点 \(i\) 和超级原点连接一条权值为 \(c_i\) 的边,跑最短路即可。复杂度 \(\mathcal{O}(m^2\log m)\).
发现图的一条性质:对于每个点,其所有入边的边权都为 \(c_i\) 。也就是 Dijkstra 的过程中,每个点只会被松弛 \(1\) 次。那么对于当前点 \(i\) ,只需找到还未访问过的合法点 \(j\) 即可。
发现上面的两个式子,左侧只和 \(i\) 有关,右侧只和 \(j\) 有关,可以将 \(l_j-t_j\) 和 \(l_j+t_j\) 分别放入两棵线段树上,这样就可以在 \(\log m\) 的时间内找到一个点 \(j\) 。而每个点只需松弛 \(1\) 次,总时间复杂度 \(\mathcal{O}(m\log m)\) 。
\(\mathcal{E}nd\)
祝大家 CSPS2022 400pts,NOIp2022 400pts,联合省选2023 600pts,NOI2023 705pts,
Arcaea potential 13.05,Phigros ranking 16.11,Lanota rating 16.38 !