杂题选做2

P8292

Submission

Code

题意:有 \(n\le 10^6\) 张卡片,卡片上有权值 \(a_i\),有 \(m\le 1500\) 次询问,每次给定 \(c_i\) 个质数(\(\sum c_i \le 18000\)),要求选择的卡片乘积整除每一个给定质数的选择方案数。

值域是 \([1,2000]\)

选法计数题,考虑容斥或者 dp。dp 显然对于大数据不好做,考虑容斥。

然后直接算方案数仍然不好做,继续考虑正难则反。枚举 \(i\) 个质数,计算至少不整除这几个质数的方案数,将可以整除他们的 \(a_i\) 全部去掉,剩下的显然随便选,设对于 \(i\) 的答案是 \(f_i\),答案就是 \(\sum_{i = 0}^{c} f_i \times (-1)^{i}\)

然后发现质数很多不好算,但是对于质因数题可以经典根号分治,对于这个题,每个数大于 \(43\) 的质因数最多只有一个,即互不影响可以暴算,所有数中不大于 \(43\) 的质因数只有 \(13\) 个,可以状压。

于是你预处理 \(f[S,i]\) 表示前几个质数的状态是 \(S\) 的情况下有 \(i\) 作为质因数的数有几个,那么容易发现对于一个状态 \(S\),它的答案就是对于一个特殊的大质因数 \(k\),如果询问对它有要求,就钦定不能一个都不选,乘上 \(2^f-1\),否则乘上 \(2^f\) 即可。

然后直接压即可。

预处理的时候可以先计值的出现次数,使用bitset,然后枚举倍数,这样总复杂度可以降低许多,基本算是 \(O(2000\times 2^{13})\)

询问复杂度 \(O(2^{13} \times (m+\sum c_i))\)

总复杂度 \(O(2^{13} \times (v+m+\sum c_i)))\)

P7518

Submission

半年前做的,但是还是可以写一下,,

题意:有一棵树,每个点有一种宝石 \(a_i\),有一个长度为 \(m\) 的序列 \(c_i\)(序列种的宝石种类互不相同),从起点到终点只能顺序拿宝石,\(q\) 次查询从 \(s_i\)\(t_i\) 的路上最多能拿多少颗。范围都是 \(2\times 10^5\)

考虑倍增。维护每个点从 \(c_1\) 开始向上跳到 \(c_{2^i}\) 最低是哪一个点,从这个点自己的颜色开始倒着按 \(c\) 跳的倍增数组,以及倍增祖先。

然后对于每组询问,离线下来将每组 \((s_i,t_i)\) 插到 \(t_i\) 上,然后进行一遍 dfs,到一个点就计算这个点对应的询问的答案。

计算方式是先从 \(s_i\) 看跳到 LCA 最多能从前往后拿到 \(c\) 中哪一个,然后二分答案 \(k\),从 \(t_i\) 上面第一个颜色是 \(k\) 的开始跳到 LCA,看两部分的答案能不能相交即可。

而离线就是为了求出每个点上面第一个颜色是 \(k\) 的点是什么,如果不离线也可以做,上主席树即可。

复杂度 \(O(q \log^2 n)\)

P8330

Submission

注:有点小锅,不数据分治第一个小点会挂,应该是小边界寄了。但是懒得弄了。

题意:有一个序列,你可以进行仅一次操作:选一个区间对其中所有数进行加 \(k\subset R\),要你求出操作后序列众数的出现次数最大值以及可能取值。\(a_i\le 10^9,n\le 2\times 10^5\),序列不全相同。

显然操作就是将一个区间中某种数变成另一种数配合操作序列外的这种数达到最大值。

考虑按照出现次数是否大于 \(\sqrt{n}\) 分成小数和大数。

那么对于大数 \(x\),可以先预处理出出现次数的前缀和(方便计算区间出现次数),我们可以枚举另一种数 \(y\),然后有两种情况:

  • \(x\) 是区间外的,则显然操作区间的左右端点都必然是枚举的 \(y\) 的出现位置。然后变成最大子段和,要求区间中 \(y\) 的出现次数减去 \(x\) 的出现次数最大。这个你将贡献分开计算,枚举右端点然后取最小的左端点即可。

  • \(y\) 是区间外的,则左右端点变成了 \(y\) 的出现位置前/后1。这时要最大化 \(x\) 的出现次数减去 \(y\) 的出现次数。

可以看出,这部分复杂度 \(O(n\sqrt{n})\)

剩下对于都是小数的。可以以区间外的数的出现位置左/右1为左右端点枚举一下,然后考虑区间内的序列的众数。

似乎不能做?冷静下来思考一下,我们要计算的众数出现次数不大于 \(\sqrt{n}\),答案也不大于。

于是可以将每个枚举端点看成ds题的询问,将其离线下来扫描线。

枚举右端点 \(k\),然后设 \(s_i\) 表示以 \(i\) 为左端点的众数出现次数,那么当 \(k\) 右移时,你考虑新加进来的这个数(出现次数大则不管),枚举它每一个出现位置,然后对于每个出现位置 \(j\) 暴力更新 \(s_{pre_j~j}\),更新方式是从后往前扫,扫到 \(S\) 不变了就不扫了。这样做复杂度是对的。因为每扫一个位置 \(\sum s_i\) 至少加一,而 $\sum s_i $ 是 \(O(n\sqrt{n})\) 级别。

然后就做完了。

P7515

Submission

题意:构造矩阵 \(a\),满足 \(a_{i,j}+a_{i,j+1}+a_{i+1,j}+a_{i+1,j+1}=b_{i,j},0\le a_{i,j}\le 10^6\)

首先钦定 \(a\) 的第一行第一列或最后一行最后一列全为0,可以构造出一个不满足值域限制的矩阵。然后显然你一次给一整行或者一整列按 \(+1,-1,+1,-1...\) 操作显然仍然满足 \(b\) 限制,于是你设 \(c_i\) 是给第 \(i\) 行的操作次数,\(d_i\) 是给第 \(i\) 列的操作次数,则有 \(0\le a_{i,j}\pm c_i\pm d_j\),这会变成差分约束,但是会出现 \(c_i,d_j\) 同正同负的情况,这时变成和分约束了。但是你发现你对 \(c_i\)\(d_j\) 进行黑白染色,容易发现变成了差分约束。然后可以建图直接做。因为是稠密图所以 bellman-ford 就能做了。

P7520

可能是洛谷机子慢或者我常数太大或者他本意想卡常,卡了好久常才过。

Submission

注意:预处理可以乱写写(不是关键常数贡献),询问注意尽量保证寻址连续(可以开一堆新指针重新排一下顺序,然后从 \(1\)\(n\) 枚举查询)。

题意简洁,不重复了。

支配有什么关系?设 \(a\rightarrow b\) 表示 \(a\) 支配 \(b\)\(x\rightarrow y,y\rightarrow z\) 时,必有 \(x\rightarrow z\),当 \(x\rightarrow y, z\rightarrow y\) 时,\(x,z\) 之间也必然存在支配关系。

于是,可以利用上述性质,发现一个节点的支配集的所有节点的导出子图构成一个团。

然后考虑构建一棵支配树。一个节点 \(x\) 在支配树上的父亲是他的支配集中除自己以外支配集最大的节点(容易看出这个节点被剩下的支配集支配)。

于是你可以暴力枚举断掉每一个点哪些点不可达求出支配集,然后根据支配集大小构建支配树。

然后对于加入一条边 \((u,v)\),考虑哪些点支配集会变化。根据上述性质不难发现,一个点的支配集变化,要么其支配树上的父亲不再支配它,要么它支配树上的父亲的支配集发生变化。

所以对于第二种情况,你每次询问 dfs 的时候继承一下父亲的状态即可。

而对于第一种情况,当且仅当删掉其父亲后,\(1\) 可达 \(u\)\(v\) 可达 \(x\) 时,它的支配集会发生变化。

对于这种情况,只需要枚举每一个点,提前预处理出删掉其父亲后 \(1\) 可以到达哪些点,以及哪些点可以到达它自己即可。

注意判断特殊情况,即当 \(u\) 就是 \(fa_x\) 时,它的支配集不会因为第一种情况变化。

复杂度 \(O(n(n+q))\)

P6628

Submission

题意:给定 \(n\le 2500\) 个点,钦定 \(m\) 条无向边(无重边无自环)和起点 \(s\),经过一条边 \((u,v)\) 的代价是 \(|u-v|\),任意两个点之间都有这样的边。求从 \(s\) 在经过钦定的 \(m\) 条边基础上到达 \(i\) 的最小代价。对于每一个 \(i\) 输出答案。

要经过每一条边,且起点终点是知道的,考虑欧拉路径。

那么枚举一个 \(i\),考虑新加进来一些边构成以 \(s\) 为起点,\(i\) 为终点的欧拉路径需要满足的限制。

  • 对于钦定的边的所有端点和 \(s,i\) 要连通。

  • 图中所有点的度数都是偶数,特别地,\(s,i\) 的度数为奇数。

那么对于第二部分,你可以先把 \(m\) 条边丢进来,然后将 \(s,i\) 的度数加一后将每个点的度数变为偶数(不难看出这样就使得其度数为奇数了)。

然后从小到大枚举每一个点 \(x\),如果度数是奇数就连一条 \((x,x+1)\) 的边,将 \(x+1\) 的度数加一后继续考虑。

不难发现,因为边权的特殊性,通过这种方式一定会花费最少代价满足限制2,且会使尽可能多的点连通(从而更好满足限制1)。

然后对于连通,你在此时的图的基础上求出新加边构成最小生成树的代价,那么这部分代价乘二加上原本的代价就是答案了。

为什么乘二?因为你加一条边会将两个点的度数变成奇数,加两次这条边就又变回偶数满足限制了。

当然,你可能会想到加边不乘二,并让一个连通块到另一个连通块新加的边尽可能让最少的点度数是奇数,最后新加一些边满足限制。但是你简单感受一下,由于边权特殊性,这么做并不会由于直接把边权乘二。

接着因为度数为 0 的点不需要考虑,所以把所有度数不为 0 的点拿出来,取出编号最近的点对的边跑最小生成树即可。复杂度 \(O(n^2 \log n+m)\)

posted @ 2022-11-04 21:30  infinities  阅读(47)  评论(0编辑  收藏  举报