做题记录
再不写要退役了,写一下做题记录。
P10350 [PA 2024] Modernizacja Bajtocji
怎么这么难,原来是题读错了,这个题的 +
操作如果两个人手上都有电脑那么这个电脑就不会再送了(相当于每个居民手上最多有 \(1\) 台电脑)。
考虑什么情况下一个居民必定有一台电脑,我们先考虑连边,发现如果连的边构成了一个环那么这个环中的所有点都一定有电脑,那么没有删除操作就好做了,在讯问时判断 \(x\) 是否属于一个环,如果属于则答案是 1
否则看是否有操作覆盖到这个点如果有则答案为 ?
否则为 0
,最后我们加上删点操作我们发现相当于加入了一个新点而对于与它属于同一个连通块内的点的代价就是会吞掉这个连通块内的一次操作,所以对于每次删除直接建一个新点并把原连通块内的操作数减一即可,查询直接查询连通块内的操作数是否大于等于 \(1\) 即可。
P5283 [十二省联考 2019] 异或粽子
感觉很板子,首先考虑把区间异或和转成前缀异或和的异或值,那么我们发现 \(k\leq 2\times 10^5\) 考虑一个时间复杂度带 \(k\) 的做法,首先我们对于每一个 \(r\) 求出其作为右端点能组成的最大的异或值,并塞入大根堆,每次从大根堆中拿出最大的并塞入这个 \(r\) 作为右端点的第 \(k+1\) 大的值即可,时间复杂度 \(O(k\times (\log{n}+\log{V}))\)。
加强一下(主要是我先写了一个非常勾史的 \(\log{V}^2\) 做法),假设 \(k\leq \frac{n\times(n-1)}{2}\) 的话怎么做,我们发现可以二分第 \(k\) 大的值,然后在可持久化 Trie 树上查询区间异或值大于等于 \(mid\) 的个数,然后我们统计出区间异或值大于 \(kth\) 的和与个数然后剩下的选第 \(k\) 大的值即可,这个做法比上面的难打 \(100\) 倍而且还要被卡常。
紫题 \(520\) 了 。
P7840 「C.E.L.U-03」重构
贪心还是太难了,我们发现一个点的度数从 \(d_i\to d_i+1\) 那么增量为 \((2\times d_i+1)\times v_i\) 而 \(d_i\to d_i-1\) 的增量为 \(-(2\times d_i-1)\times v_i\) 那么考虑贪心,我们每次拿出 \((2\times d_i+1)\times v_i\) 最小的和 \((2\times d_i-1)\times v_i\) 最大的然后看是否换了之后更优就行了,时间复杂度我也不会证明,注意这里要判断这个点的度数是否可以加或减,一开始让所有点都连上一个点就行了(即是一棵菊花)。
P8162 [JOI 2022 Final] 让我们赢得选举 / Let's Win the Election
太难了,首先考虑一个错的贪心,我们按 \(b_i\) 排序然后枚举多选多少个人,直接拿前 \(k\) 小的 \(b_i\) 然后在从小往大拿 \(a_i\) 即可,但是我们发现这样是错的因为可能有一个 \(a_i\) 非常小而 \(b_i\) 也不算大但是这个拿 \(a_i\) 更优,但是这个贪心中有一部分是对的,第一个是一定先增加人在拿票,第二个是增加人的顺序一定按照 \(b_i\) 从小往大,所以我们考虑 dp,我们定义 \(f_{i,j}\) 表示 \(b_i\) 前 \(i\) 小的有选了 \(j\) 人的最小代价,那么剩的直接按照 \(a_i\) 从小往大排序选择即可。
P6815 [PA 2009] Cakes
套路题啊,看这个,应该可以得到一个 Trick 就是一个边数为 \(m\) 的无向图中三元环的个数最多有 \(m\sqrt{m}\) 个。
P6820 [PA 2012 Finals] Two Cakes
感觉不好自己想到啊,首先我们可以很轻松的想出一个 \(n^2\) 的 dp,我们定义 \(f_{i,j}\) 表示第一个写到 \(i\) 第二个写到 \(j\) 的最小时间,那么转移就是若 \(a_i=b_j,f_{i,j}=\min(f_{i-1,j},f_{i,j-1})+1\) 否则 \(f_{i,j}=f_{i-1,j-1}+1\),我们乍一看这个东西好像无法优化,但是我们又发现这个题目保证了 \(a,b\) 均为排列,所以我们发现对于第一种情况最多只会出现 \(n\) 次,而对于第二种我们所有的转移都是规律的即 \(f_{i,j}=f_{i-k,j-k}+k\) 所以考虑记忆化搜索,我们对于每次的 \(i,j\) 分讨,如果 \(a_i=b_j\) 则递归 \((i-1,j),(i,j-1)\) 即可,否则我们找到最大的 \(k\) 使得 \(a_{i-k+1}=b_{j-k+1}\) 这个我们直接把下标塞入一个位置差的桶中二分即可。
P5992 [PA 2015] Rozstaw szyn
so hard,考虑一个贪心,对于一个点 \(x\) 我们不考虑 \(x\) 于其祖先的贡献,那么 \(x\) 取所有儿子的值的中位数即可,但是我们发现如果儿子个数为偶数我们无法知道取哪一个,不妨我们把一个点的取值变成一个区间 \(l_x\sim r_x\) 那么我们发现对于一个点 \(x\) 直接把所有儿子的区间左右端点都放入序列中排序之后取中位数又组成一个区间,那么我们进行一次 dfs 之后每一个点都有一个取值范围 \(l_x\sim r_x\) 然后我们分讨一下这个点取谁能更优即可,我也不会证明放区间左右端点的东西,可以感性理解一下。
P5997 [PA 2014] Pakowanie
不是很难,首先我们可以发现 \(c_i\) 一定从大到小排序一个一个放,然后我们定义 \(f_{i,j}\) 表示用了前 \(i\) 个包放了状态为 \(j\) 的物品第 \(i\) 个包能剩的最大的容量,转移就是 \(f_{i,j}-a_k\to f_{i,s}\) 以及 \(c_{i+1}-a_k\to f_{i+1,s}\) 然后我们发现这样的时间复杂度是 \(2^n\times n\times m\) 完全不可过,通过观察我们可以发现背包个数最多用 \(n\) 个就行了,那么只保留前 \(\min(n,m)\) 大的背包即可,时间复杂度 \(2^n\times n^2\) 卡卡常能过。
P10357 [PA 2024] Żelki
不是很难,首先我们考虑如何满足每种种类的糖豆个数都要一致,我们假设每种取了 \(k\) 个,那么我们对于最后的方案一定能拆成每种只选 \(1\) 个的 \(k\) 组合并起来,于是我们考虑定义 \(f_{i,j}\) 表示选了前 \(i\) 中每种一个重量之和模 \(m\) 为 \(j\) 的最小代价,然后我们考虑跑一个同于最短路即可。
P9097 [PA 2020] Elektrownie i fabryki
简单题,首先我们考虑一段合法的区间长什么样子,我们发现对于区间 \(l\sim r\) 如果可以划分出来一定有 \(\sum_{i=l}^{r}a_i\geq0\) 然后我们再将其转成前缀和就是 \(s_r-s_{l-1}\geq 0\) 然后定义 \(f_i\) 表示前 \(i\) 个都分配好了的最小成本,所以 \(f_i=\min(f_j+(j-i-1)),s_i-s_j\geq 0\) 那么这个直接树状数组优化即可。
P11915 [PA 2025] 瞬间传送 / Teleport
有点牛,不会贪心所以写了个 \(\frac{n^4\times \log{n}}{w}\) 的东西,但是跑得很快,首先我们考虑二分答案 \(ans\) 然后我们先枚举加入的边的端点 \(u,v\),不难发现对于一对 \(i,j\) 不合法当且仅当 \(dis_{i,j}>ans,dis_{i,u}+dis_{j,v}>ans,dis_{i,v}+dis_{j,u}>ans\) 那么我们考虑枚举 \(i,j,u,v\) 其中的三个,不妨就枚举 \(u,v,i\) 然后我们只需要判断是否存在 \(j\) 即可,我们将上面的后两个柿子移项可以得到 \(dis_{v,j}>ans-dis_{i,u},dis_{u,j}>ans-dis_{i,u}\) 所以可以得出对于这个 \(j\) 需要满足 \(dis_{i,j}>ans,dis_{v,j}>ans-dis_{i,u},dis_{u,j}>ans-dis_{i,v}\) 所以我们对于每个点处理出来一个 bitset,\(f_{i,j}\) 表示 \(dis_{i,x}>j\) 的所有 \(x\) 在查询时只需要将 \(f_{i,ans},f_{u,\max(0,ans-dis_{i,v})},f_{v,\max(0,ans-dis_{i,u}}\) 并起来看是否有位置是 \(1\) 即可。
P6223 [CHCI 2009 Final Exam #1] PODJELA
不难,首先不难想到树形 dp,然后可以得出一棵大小为 \(x\) 的子树的操作数不会超过 \(x-1\) 次,然后我们转化题意为把每个点的点权设为 \(x-a_i\) 然后求最小的次数使得每个点的点权 \(\geq 0\) 的最小次数,考虑 dp,定义 \(f_{i,j}\) 表示使得 \(i\) 子树中除了 \(i\) 的点都满足条件用了 \(j\) 次操作第 \(i\) 个点的最大权值,那么转移为 \(f_{u,j}+f_{v,k}\to f_{u,j+k+1}\) 就是将 \(v\) 这个点的点权也给 \(u\) 然后还有不把 \(v\) 给 \(u\) 但是需要保证 \(v\) 的点权合法即 \(f_{v,k}\geq 0,f_{u,j}\to f_{u,j+k}\),最后只需要输出满足 \(f_{1,i}\geq 0\) 的最小的 \(i\) 即可。
P4810 [COCI 2014/2015 #3] STOGOVI
不难,首先我们考虑如何维护加入栈顶和踢出栈顶的操作,我们发现我们可以把一个栈维护成一条链,那么每次就是在一条链末尾加一个点或者是跳到一个点的父亲,那么对于前两个操作就很好维护了,对于查询操作有一个想法就是你维护一条从根节点开始的链的 bitset 即哪些权值出现过然后并一下就行了,但是我们发现 \(n\leq 3\times 10^5\) 时间复杂度炸了,通过观察我们发现每次加入的数都一定是不同的,所以直接查询树上两个点的 lca 的深度即可。
P4422 [COCI 2017/2018 #1] Deda
没脑子题,三位偏序板子题,难点在于读懂题。
P4616 [COCI 2017/2018 #5] Pictionary
不难,首先我们可以枚举在第 \(i\) 天会合并的那些点然后我们就可以用一个并查集维护是否合并过了,我们发现最后一定会建出来一棵树,那么对于 \(x,y\) 的答案就是 \(x\sim y\) 路径上的最大值了,在并查集合并的时候把 \(x,y\) 这条边的边权设成 \(i\) 即可。
P5052 [COCI 2017/2018 #7] Go
考虑区间 dp,我们定义 \(f_{i,j,k,0/1}\) 表示我们走过 \(i\sim j\) 现在在左端点还是右端点以及当前时间是 \(k\) 的最多能收集的糖果数,我们发现如果其走过一个点则一定不会走回去,所以区间 \(i\sim j\) 一定只会往大扩展,但是我们发现这个时间复杂度是 \(n^3\) 的无法通过,通过观察可以发现 \(i,j\) 中只用存有糖果的就行了,所以我们 \(i,j\) 表示为走过区间 \(a_i\sim a_j\) 的答案,这样就把之间复杂度降到了 \(m^2n\) 可以通过,好像还可以通过换维可以降到 \(m^3\) 但是这题前一个就能过了就没优化了,在做题时还不小心 hack 了三篇题解,/tx。
蓝题 \(666\) 了。
P4957 [COCI 2017/2018 #6] Alkemija
这题有点厉害,不知道如何想到,首先我们对于每一个操作都新建一个点 \(x_i\) 然后将 \(l\) 个原材料都连向 \(x_i\) 又让 \(x_i\) 连向 \(r\) 个成果,那么我们发现这样假设我们遍历到的点都是能得到的,如果一个 \(x_i\) 的 \(l\) 给点都被遍历到了则可以加入 \(r_i\) 个成果,考虑一个类似拓扑排序的东西对于每个 \(x_i\) 记录入度我们发现如果一个点的 \(dg_i=0\) 了就可以把他的成果全部标记为可以然后减掉所有出边的虚点的入读即可,这样每个材料只能遍历一遍而且对于每一个虚点也只会遍历一遍,时间复杂度是 \(n+\sum (l_i+r_i)\) 的,感觉还是不好想到在图上搞。
P6319 [COCI 2006/2007 #3] LISTA
StayAlone好强,/bx。
大胆猜结论题,首先可以用队列得到最终序列长什么样子,然后大胆猜测答案的最小次数为 \(n\) 减去最长上升子序列长度,通过样例可以证明,然后我们思考如何构造可以发现最长上升子序列上的点把权值切成了一块一块的,那么对于每一块只需要看是往后移还是往前移即可,时间复杂度 \(n\log{n}\),结论不会证明但是过了就不管了。
P11535 [NOISG 2023 Finals] Airplane
性质题,首先发现直接做不好做,考虑观察性质,我们发现对于一个最优解一定可以刻画成一个前缀在不停上升,一个后缀在不停下降,中间的一段高度不变,又通过观察可以发现中间一段的长度一定小于等一 \(1\) 因为如果大于 \(1\) 那么一定可以调整成前面的先上升后面一部分下降,那么我们直接从 \(1,n\) 跑一遍到每个点的最短路即可,最短路的更新为 \(f_{to}=\min(\max(f_{u}+1,a_{to}))\)。
P7962 [NOIP2021] 方差
妙妙题,通过观察可以发现一次操作之后,等同于交换相邻的两个差分值,有一个结论是使得方差最小的时候差分数组一定是先递减后递增的(相当于一个单谷),又有一个结论是对于值域在 \(v\) 的单调数组其差分数组中出现的值的数量在 \(\sqrt{v}\) 左右,那么我们发现 \(a_i\leq 600\) 所以差分数组的权值个数只有 \(20\) 左右那么直接 \(2^k\) 爆搜是放左边还是右边以及放多少个即可,虽然不是正解但是过了,/tx。
P7114 [NOIP2020] 字符串匹配
不难,首先我们发现可以枚举 \(AB\) 的长度和 \(i\) 那么通过枚举这两个就可以得到 \(C\) 了,我们可以通过预处理来算出 \(C\) 的 F 值,然后我们就变成了统计一个前缀中有多少个数的 F 值 \(\leq k\) 直接在扫前缀的时候开桶记录即可,判断 \({AB}^{i}\) 是否和一个前缀相等直接用哈希判断即可,时间复杂度 \(n\times \ln_{n}+n\times 26\)。
P6418 [COCI 2014/2015 #1] ZABAVA
不难也好写,但是我为啥写了这么久啊。
首先我们发现两栋楼之间是互不影响的,那么考虑定义 \(f_{i,j}\) 为第 \(i\) 栋用了 \(j\) 次清空能得到的和的最小值,考虑如何处理这个东西我们发现用了 \(j\) 次能分成 \(j+1\) 组那么每一组先给 \(cnt_i\div (j+1)\) 个人然后在给剩下的 \(cnt_i\bmod (j+1)\) 组每组一个就行了,然后在定义 \(g_{i,j}\) 为前 \(i\) 栋用了 \(j\) 次的最小值,直接 dp 即可。
P5184 [COCI 2009/2010 #2] PASIJANS
简单题,有一个一眼的贪心是每次选取字典序最小的把第一个拿出来即可,而如何做到那字典序最小的呢,可以后缀数组,但是我不会所以直接二分加哈希就行了,二分第一个不同的位置,但是有一种特殊情况就是如果两个字符串一个是另一个的前缀要优先取剩余字符串多的那个。
AT_cf16_exhibition_final_e Water Distribution
妙妙题,首先我们发现 \(n\leq 15\),考虑一种做法是对于两个点之间如果要相互给就连一条边我们发现对于一个连通块中每个点能拿到的最大值是 \(s\) 减去边权的最小值之和的平均数,那么对于边权最小值就是最小生成树了,那么直接定义 \(f_i\) 为联通了 \(i\) 中的点的最小值,在合并若干个 \(f_i\) 即可,直接枚举子集转移即可。
P7868 [COCI 2015/2016 #2] VUDU
简单题,首先我们发现对于一个合法区间 \(l\sim r\) 可以写出柿子为 \(s_{r}-s_{l-1}\div(r-l+1)\geq p\),那么又把 \(l-1\) 变成 \(l\) 即 \(\frac{s_r-s_l}{r-l}\geq p\) 然后打开变成 \(s_r-s_l\geq p\times (r-l)\to s_r-r\times p\geq s_l-l\times p\) 直接树状数组即可。
P3486 [POI 2009] KON-Ticket Inspector
简单题,题面好像有点问题,要强制选 \(k\) 个。首先不难想到是个 dp,直接定义 \(f_{i,j,k}\) 表示到 \(i\) 站上一次检票在 \(j\) 一共用了 \(k\) 次的最大值,转移直接分讨这一站是否检票即可,我们发现只用求出这一战能检到多少个上次没有的人,我们列成偏序关系就是 \(lst<l<i,r>i\) 的 \(a_{l,r}\) 之和,这个直接前缀和处理即可,很简单,时间复杂度 \(n^2\times k\)。