QOJ 板刷记录3

2025.8.25 开始第三篇记录


#30. Political Development

简述题意

给一个图,满足对于任意点导出子图,存在一个节点的度数小于 \(k\),求原图的最大团。

题解

比较水,根据题意,你考虑最开始肯定有一个点度数小于 \(k\),那我们就可以暴力把它连向的点拉出来,状压记录好这些点之间互相的连通性,然后直接枚举这些点中哪些点是一个团的,这个枚举是 \(O(2^k)\) 的,由于我们提前记好了这些点之间的是否连边,我们可以直接做到需要 \(O(k)\) 判断枚举的这些点是否成团,如果可以,更新答案。这么做完,我们就把第一个点在团内的情况判断完了,接下来我们把这个点删掉,根据定义,剩下的子图肯定还有度数小于 \(k\) 的,然后还按照做第一个点的办法做第二个点,以此类推,做一个类似拓扑排序的东西就做完了,时间复杂度 \(O(n2^kk)\)


#31. Railway

简述题意

要求你维护一棵树的所有边,每次给定 \(m\) 个结点,要求你选择最少的边,使得这 \(m\) 个点连通。把所选边的边权 \(+1\) ,最后询问有多少条边的边权大于等于 \(k\)

题解

比较水,你发现选几个点让他们连通需要的最少边就是把这几个点建虚树上的边,然后只需要建虚树的时候每次连边都做树上差分把对应的链整体 \(+1\),最后统计一下就做完了。


#32. Toll

简述题意

给你一个有向图,边有边权,保证对于任意一条边 (\(u\),\(v\)),都有 \(\lfloor\frac{v}{k}\rfloor=\lfloor\frac{u}{k}\rfloor+1\),其中 \(k<5\) ,现在有 \(q\) 次询问,每次询问两个点之间的最短路。

题解

非常唐,假如我们按照题意把所有点按照除以 \(k\) 向下取整分成若干组, 你发现一个点显然只能从上一组的点过来,所以就有 \(dis[v]=Min_{\lfloor\frac{v}{k}\rfloor=\lfloor\frac{u}{k}\rfloor+1}dis[u]+e[u][v]\)\(e[u][v]\) 为两个点之间的边权,我们很自然可以把这个东西写成矩阵的形式(\(Min-Add\)),这样一个向量乘以这个转移矩阵就可以从一组点转移到下一层的一组点,那要转移若干层呢?我们只需要拿一个线段树维护矩阵的乘积,这样询问 \(u\)\(v\) 的最短路只需要把初始向量设置为 \(u\) 处为 \(0\) 别的地方都是 \(inf\),然后乘以 \(u\)\(v\) 之间层的矩阵的乘积,然后在 \(v\) 对应的位置就可以知道 \(dis[v]\) 了。


#33. Cat in a tree

简述题意

给你一颗 \(n\) 个节点的树,需要找出最大的点集,使得其中任意两点距离都大于 \(k\) (所有边权均为 \(1\)

题解

妙妙题。设 \(dp[i]\) 表示以 \(i\) 为子树能选出最多多少个点。根据经典树上 \(\text{dp}\) 套路,我们需要从下往上,将子树一个一个合并,就能的到当前点的 \(\text{dp}\) 值。首先你需要观察到一个显然的性质,如果能选更深的点一定不会选择更浅的点。毕竟我们在从下往上考虑,比较浅的点肯定会影响我们使后面的状态更容易不优。所以根据贪心策略,从下往上考虑的时候,由于选取更深的点对后续限制更小,故贪心选取最深可行点是最优的,如果能选的点,我一定要选,我肯定没有必要留着选更浅的点。

接下来,我们观察到一个很重要的性质,对于任意点 \(v\) 对它的父亲 \(u\)\(\text{dp}\) 值做的贡献一定是 \(dp[v]\) 或者 \(dp[v]-1\)

证明如下:

假设 \(d1\) 是 当前 \(u\) 已经计算贡献的子树中选择的深度最浅的点到 \(u\) 的距离,\(d2\) 是次浅的。 \(d3\)\(v\) 子树下选择的最浅的点,\(d4\) 是次浅的。根据题意一定有 \(d1+d2 \ge k\)\(d3+d4 \ge k\)

  • 假如 \(d1+d3\ge k\),那么根据贪心取的策略我们把 \(v\) 子树要选的点都选了,也就是说 \(v\) 的贡献就是 \(dp[v]\)。显然不存在更优的方案。
  • 假如 \(d1+d3<k\),我们选择把 \(d1\)\(d3\) 中较小的删掉,再把剩下的点该取的全取了,这样一定是合法的,因为我们删掉的是深度较小的点,根据 \(d1+d2 \ge k\)\(d3+d4 \ge k\),最浅的点在它对应的子树都合法,\(d1\)\(d3\) 中较深的肯定更合法了。也就是说 \(v\) 的贡献就是 \(dp[v]-1\) 了,删除点其实也相当于一个反悔操作了。

所以我们对于每个点在维护 \(\text{dp}\) 之外,在维护一个选择的点中最浅的点到它的距离,令其为 \(d[u]\)

则有:

  • \(d[u]+d[v]>k\) ,说明 \(u\)\(v\) 子树中最浅点距离 \(>k\) ,可同时保留,故:

    \(dp[u]←dp[u]+dp[v],d[u]←min(d[u],d[v])\)

  • 否则需舍弃一个最浅点(贪心舍弃较浅者),故:
    \(dp[u]←dp[u]+dp[v]−1,d[u]←max(d[u],d[v])\)

  • 边界处理:若 d[u]≥k ,可额外选取 u 本身:

\(dp[u]←dp[u]+1,d[u]←0\)
时间复杂度 \(O(n)\)


#34. Friends

题意简述

\(n\) 个人,互相之间有朋友关系(要求必须双向的),要求把这几个人分组(一个人只能在一个组里),要求每组最多 \(p\) 个人,并且要求组内每人 "在组外的朋友数量" 之和小于 \(q\)。判断是否有解,若有解构造分组方案。

困难题,不会。

题解

我们首先可以观察到一个性质,假如一个人可以出现在多个组之中,我们能找到一个满足其他条件的划分组的办法,那么就一定有解。想要证明这个性质,我们只需要证明任意两个合法但是有交的组可以通过手段使它们无交。

我们只需要证明 \(A\)\(B\) 是两个合法组,它们的交集是 \(C\),那么一定有 \(A \setminus C\) 或者 \(B\setminus C\) 是合法组 。这样两个有交的组就可以被划分为无交的。

证明如下:

首先我们设 \(a\) 为朋友中一个人在 \(A\setminus C\),另一个人在 \(C\) 的对数,\(b\) 为朋友中一个人在 \(B\setminus C\),另一个人在 \(C\) 的对数,\(c\) 为朋友中一个人在 \(C\),另一个人在既不在 \(A\) 也不在 \(B\) 的组的对数。那么显然 \(A\setminus C\) 相对于 \(A\) 组内每人 "在组外的朋友数量" 之和的变化量为 \(a-b-c\)\(A\setminus C\) 相对于 \(A\) 组内每人 "在组外的朋友数量" 之和的变化量为 \(b-a-c\)。显然 \(a-b\)\(b-a\) 是相反数,至少有一个小于等于 \(0\),也就是说至少有一个会使组内每人 "在组外的朋友数量" 之和变少,也就是肯定合法,所以我们就证完了。

所以我们就只需要找出一种所有合法组(不满足无交的性质)包括所有人,如果找不出就是无解,如果找出来然后我们 \(n^2\) 枚举组别,然后给两个组其中的一个去除交集就好了,这部分时间复杂度是 \(O((n^2+m)p)\) 的。

那么如何找到一种并包含所有点的方案呢?我们对于枚举一个点,找到一个包含这个点的合法组就好了,这一部分我们可以选择暴搜,维护一个已经选了的点集,和待选点集(显然待选点集和选了的点集中的某个点互为朋友关系),和被确定一定不能选的和待选点集中某个点互为朋友的点,如果已选点集的大小大于 \(p\) 显然可以剪枝,待选点集+已经选点集+确定一定不选点集大于 \(p+q\) 也可以剪枝,当前组中 "不在该组的朋友数量和" \(> q\) 时也能剪枝,简单分析一下时间复杂度,对于一个点可能成为候选队列的最多只有 \(p+q\) 个点,否则肯定会被剪枝,每个点都有可能取有可能不取,其实时间复杂度就是 \(2^{p+q}(p+q)+m\) 的一共\(n\) 个点,总共的时间复杂度就是 \(n2^{p+q}(p+q)+nm\)的。


#35. Plus Minus

题意简述

\(n\times m\) 的网格,每个网格上面填 \(0\) 或者 \(1\),已经确定 \(k\) 个格子的取值,要求任意 \(2\times 2\) 的子区间都要求 \(0\) 的个数和 \(1\) 的个数一样多,问有多少种合法填法。

题解

性质题。手玩一会就会发现,只要第一列不是 \(01\) 交替,那么后面的所有数都一定是唯一确定的,因为对于任意一个连续的长度大于 \(2\)\(1\) 或者 \(0\) 连续段,对应的下一列中,这个连续段显然就是上一列 \(01\) 翻转,只要有一个数确定了,肯定这一列也确定了,因为上一列我们是知道的,因为我们把确定的数和上一列的两个数正好可以凑出来三个数,留一个角,那个角也是唯一确定的,这其实就相当于向上向下拓展了,最后一列就全被确定了,我们发现拓展完一定是和上一列完全 \(01\) 反转的。至于如果第一列如果不是 \(01\) 交替,那么下一列就不能确定出一个数,自然就不是唯一确定的了,但是下一列肯定显然也是 \(01\) 交替的,即要么和上一列相同要么 \(01\) 反转,我们只需要先求出来如果第一列是 \(01\) 交替的有多少情况,这一部分我们先判断有没有冲突的,即某一列填完数一定不能 \(01\) 交替,如果没有冲突,只要有一列有数,那么这一列的 \(01\) 交替方式就唯一确定了,假如有 \(x\) 列有数,那么没有数的列肯定两种交替方法都可以选,也是就有 \(2^{m-x}\) 中填法。那另一种情况呢?那就只能每一列都和上一列 \(01\) 反转,我们还是先判断有没有冲突的,即奇数和偶数列的同行的位置填的数相同或者奇偶性相同的列有同行填的数不同。如果没有冲突,那么假如一行有数 那么这一行在第一列填的数就唯一确定了,如果没有就是有两种填法无所谓,假如有 \(y\) 行没有数,那么答案就是 \(2^{n-y}\)。答案就是两者相加,但是不要忘记第一列假如 \(01\)交替后面也有可能每一列都是和上一列 \(01\) 反转的,所以这种情况可能在两种情况下都算了,我们特判这种情况合不合法,如果合法扣掉就好了,然后就做完了。

posted @ 2025-08-29 16:29  Cybher  阅读(26)  评论(0)    收藏  举报