一些题(三)
[集训队作业2018] Simple Tree
树剖+序列分块直接卡过去了。
https://uoj.ac/submission/514035
[PA2012] Tax
一个暴力的想法是把一条无向边拆成两条有向边,把拆出来的边当作新图的点,建边 \((u,v)\) 到边 \((v,w)\) 的边权为原图两边较大值的边,答案为从 \(1\) 出发的边到以 \(n\) 结束的边的(加上这两条边边权)的最短路(可以建超级源/汇求)。
这样的边数是 \(O(m^2)\) 的,考虑优化它。利用差分,将从 \(u\) 出发的边按边权排好序,相邻两边中小的向大的连边权为差值的边,大的向小的连 \(0\) 边。然后连 \((u,v)\) 到 \((v,u)\) 的边权为原边权的边,就对了。
[IOI2014] Friend
考虑倒着删点,把 \(i\) 的点权叠加在 \(host_i\) 上,三种连边方式分类讨论即可。
https://uoj.ac/submission/514308
[IOI2015] Sorting
二分答案,然后发现可以把对面的操作全部放到前面做完(\((x,y)(y,z)=(x,z)(x,y)\)),贪心判断即可。
https://uoj.ac/submission/514384
[IOI2016] molecules
由于它保证的性质,排完序后选择合适的长度从小到大滑动窗口就不会错过答案(如果存在的话)。
https://uoj.ac/submission/514394
[IOI2016] messy
看到这个 \(n\log n\) 的限制,想到分治。对于一个区间,将左半边每个位置依次设为 \(1\),其它为 \(0\),就可以询问出左半边的像,然后递归下去做。为了不让各个区间的询问冲突,询问 \([L,R]\) 时将 \([n]\setminus[L,R]\) 都设为 \(1\) 即可,由于还原时也是递归进行的所以这些位置的像已经知道了,不影响当前区间。
https://uoj.ac/submission/514420
[IOI2014] Rail
先 \(n-1\) 次问出 \(0\) 到所有点的距离,然后找到最近的,它一定是 \(0\) 右边的第一个 D,设为 \(p\)。然后用 \(n-2\) 次问出 \(p\) 到所有点的距离,这样就可以分辨出那些点在 \(0\) 左边/ \(0\) 和 \(p\) 之间/ \(p\) 右边。对于中间的,它们一定是 C,并且位置也确定了。对于右边的,可以按到 \(0\) 的距离排序,从小到大依次扫过去,通过它到当前确定的最右的 D 的距离来确定它到底是 D 还是 C,左边同理。
https://uoj.ac/submission/514470
[IOI2015] Towns
首先可以通过 \(2n\) 次询问问出直径,同时算出每个点在直径上第一个连到的方点,就容易求出半径了。
考虑判断一个点是否是重心,即是否存在一个子树大小超过 \(n/2\)。注意到确定两个连到它的圆点可以一次询问判断在不在一个子树内,而其它圆点可以直接判断。
于是问题转化为 \(n\) 个数,至多可以进行 \(1.5n\) 次询问两数是否相等,判断是否有数出现次数 \(>n/2\)。一个方法是维护当前可能的答案 \(u\) 和此时的比其他数多的出现次数 \(c\),当遇到一个 \(v\) 时:
- 若 \(c=0\),那么 \(u\gets v,c\gets 1\);
- 否则若 \(u,v\) 相等,那么 \(c\gets c+1\);
- 否则 \(c\gets c-1\)。
那么若最后 \(c>0\) ,才可能有答案,并且答案只可能是 \(u\),只需要对 \(u\) 进行判断即可。这样看起来是 \(2n\) 次的,但是发现对于出现第二种情况的 \(v\) 可以不再进行询问,而这样至少可以节省 \(0.5n\) 次。
https://uoj.ac/submission/515303
[IOI2017] Wiring
假如所有红点都在所有蓝点的左边,那么答案为 \(\sum (r_{n-1}-r_i)+\sum (b_i-b_0)+\max\{n,m\}*(b_0-r_{n-1})\)。
对于一般情况,每一个同色连续段一定会有一个分界点,使得左边的向左连,右边的向右连,代价就是上面那个式子。于是拆 \(\max\) 顺序 dp 即可。
https://uoj.ac/submission/515446
UOJ175 新年的网警
手玩一下,发现一个点可以伪装当且仅当至少满足以下条件中的一个:
- 存在另一个点与它邻居(除去对方)相同;
- 它的度数为 \(1\);
- 存在一个邻居的度数为 \(1\)。
瞎哈希判一判就好了。
https://uoj.ac/submission/515484
UOJ176 新年的繁荣
Boruvka 板子,用类似高维前缀和的东西维护最长距离。
https://uoj.ac/submission/515615
CF888G Xor-MST
Boruvka 板子,用 trie 维护最短距离。
https://codeforces.com/contest/888/submission/134315422
[Ynoi2008] stcm
轻重链剖。递归解决某一重链时假设其连顶的子树补已经全被标记,那么重链上的点可以直接从上到下暴力加点暴力回溯。对于轻子树,可以建一棵以子树大小为权值的哈夫曼树,然后在哈夫曼树上递归:标记右子树递归左子树,回溯,标记左子树递归右子树,回溯。这样次数是 \(O(n\log n)\) 的,能过。
https://www.luogu.com.cn/record/62072297
[POI2017] Turysta
首先 SCC 缩点,那么一个点能到的点就是所有拓扑序大于等于它的点。为了构造方案,需要对每个 SCC 找到一条哈密顿回路。可以先增量构造出一条哈密顿路径,然后将这条路径上第一个点作为初始的环,之后每当有点向这个环连边时就把这个点之前的点都加进环里。