tg 26 题解
乱序模式开启
T3
一个二维的最短路题
就是两个点一起走,在正反图上同时跑
对于每一个状态维护一个std::bitset
它的含义就是每个点是否在当前状态(以及之前状态)经过
走到\((n,n)\)的时候取出就好了
数据不强,这里有一组数据可以卡掉各种乱搞做法
T4
首先可以删除被某个矩形完全包含的矩形,这些矩形对答案没有影响。
判断一个矩形是否被完全包含可以限定矩形三条边的范围,求最后一条边的极值,
这是一个三维偏序问题,可以\(O(nlog^2n)\)解决。
处理完后,
任何两个矩形相交当且仅当它们在边界上相交,
而且一定会出现一条横边与一条竖边相交这种十字形交叉。
考虑dfs求连通块的个数,
现在的任务是找到任意一个和当前矩形相交的矩形,
也就是给定一条横边(竖边),找出任意一条与这条横边相交的竖边(横边)。
发现这实际上是个二维的问题,可以用线段树套 set 解决。
开两棵线段树,一棵处理横边,一棵处理竖边即可。
时间复杂度\(O(nlog^2n)\),空间复杂度\(O(nlogn)\)
有一种乱搞做法:
就是对于所有的矩形按照坐标排序
如果两个矩形判定相交,对于这个矩形的计数器\(+1\)
同时合并两个矩阵并查集
如果计数器\(>4\)就直接跳过
这个能A
T2
首先注意到每次操作至少会删去一半的元素,所以操作最多只会执行log次。
把数组从最大值的部分切成两部分,
发现左右两边是互不干扰的子问题,
左右两边又可以分别找到最大值再递归下去...
考虑在笛卡尔树上dp。
除了根节点在最后统计答案的时候需要特判一下之外,
笛卡尔树上每个子树代表的区间有两种情况:
有一边挨着边界,另一边挨着一个比区间内所有数都大的数;
两边都挨着一个更大值。
设 \(f[i][j][0/1]\)表示两种情况下一个长度为\(i\)的区间需要\(j\)次删完的方案数。
转移枚举区间内最大值的位置,区间最大值被删除的时刻就是挨着一个更大值的子区间被删完的时间的最小值\(+1\)。
转移可以用前缀和优化,时间复杂度\(O(n^2logn)\)。
T1
把从k开始往左和往右看成两个序列,再分别求一次前缀和,
问题变为:
给定两个序列\(a[1..n],b[1..m]\),开始时\(i=j=1\),每次可以把\(i\)或\(j\)增加\(1\),
需要保证任意时刻\(a[i]+b[j]<=0\),问能否把\(i\)和\(j\)同时移到末尾。
分别找到 \(i\) 和$ j$ 之后第一个更小的位置,
如果能把某个指针移过去显然会贪心的移过去,
如果两个指针都移不了了答案显然是\(No\)。
这样只能把\(i\)和\(j\)移到数组中最小值的位置,
但是发现后一半的移动倒过来就和前一半的移动等价,
所以可以直接把两个数组倒过来走回最小值的位置。
至此在线性时间内解决了本题。

浙公网安备 33010602011771号