比赛记录

CF2039

C1 Shohag Loves XOR (Easy Version)

\(y \le x\) 的情况显然可以暴力解决。只需考虑 $y > x $ 的情况。
考虑一个性质:如果 \(d\)\(p\) 的一个因子(\(d \ne 1\)),有 \(d \le \lfloor \frac{p}{2} \rfloor\)。又因为下取整与右移等价,所以 \(d,p\) 的最高位不同。
考虑 \(x \oplus y\) 的取值,如果 \(x \oplus y\)\(y\) 的因子,这要求 \(x \oplus y \le \lfloor \frac{y}{2} \rfloor\),即 \(x \oplus y\)\(y\) 的最高位不同。由于 \(y > x\),当 \(y\) 的位数与 \(x\) 的位数不同时,即 \(y \ge 2x\) 时,\(x \oplus y\) 的最高位与 \(y\) 的最高位相同了,矛盾。因此只有 \(y < 2x\) 时,\(x \oplus y\) 可能是 \(y\) 的因子。
如果 \(x \oplus y\)\(x\) 的因子,这要求 \(x \oplus y < x\),但是当 \(y \ge 2x\) 时,\(x \oplus y\) 的位数与 \(y\) 相同,显然 \(x \oplus y > x\)。因此,只要考虑 \(y < 2x\) 的情况就好。

C2 Shohag Loves XOR (Hard Version)

妙妙题。挺深刻的。
考虑异或的性质:\(|x - y| \le x\oplus y \le x +y\)
考虑容斥,计算 \(x \mid x \oplus y\) 的个数加上 \(y \mid x \oplus y\) 的个数减去 \([x,y] \oplus y\) 的个数。
考虑计算 \(x \mid x \oplus y\) 的个数。记 \(x \oplus y = kx(k>1)\),那么 \(x \oplus kx = y\)。只需计算 \(x \oplus 2x, 3x, \cdots kx\) 得到的 \(y \le m\) 的个数。由于 \(kx - x \le x \oplus kx \le x + kx\),因此 \(x + kx \le m\)\(k\) 肯定满足,\(kx - x > m\)\(k\) 肯定不满足。中间的 \(k\) 不会很多,暴力判断即可。
计算 \(y \mid x \oplus y\) 的个数。记 \(x \oplus y = ky\),有 \(y \oplus ky = x\)。又因为 \(y \oplus ky \ge ky - y \ge y\),因此 \(y \ge x\) 时肯定不满足。暴力枚举 \(y < x\) 即可。
计算 \([x,y] \mid x \oplus y\) 的个数。在上面枚举 \(y\) 的时候同步计算即可。
时间复杂度 \(O(x)\)

D Shohag Loves Inversions

手玩一下。记 \((x,y)\) 表示 \(\gcd(x,y)\)
考虑 \(i=1\) 时,这时对于 \(\forall j \in [2,n]\),需满足 \(a_1 \ne (a_1,a_j)\)
考虑 \(i=2\) 时,这时分讨 \(j\)

  • 对于 \(i \mid j\),有 \(a_i \ne (a_2, a_j)\)
  • 对于 \(i \nmid j\),有 \(a_{(2,j) = 1} \ne (a_2,a_j)\)

考虑第二种情况,由于 \(i=1\) 时已经确定了 \(a_1 \ne (a_1,a_2)\)\(a_1 \ne (a_1,a_j)\),这时要满足 \(a_1 \ne (a_2,a_j)\),巧妙的构造是令 \(a_2,a_j < a_1\),由于 \((x,y) \le \min(x,y)\)\((a_2,a_j)\) 必定 \(< a_1\),满足条件。
推广一下。对于 \(i < j\)\(i \mid j\) 的二元组 \(i,j\),构造 \(a_j < a_i\)
对于 \(i < j\)\(i \nmid j\) 的二元组 \(i,j\),记 \(d = (i,j)\),转化成 \(d,i\)\(d,j\) 两个二元组,满足要求。
考虑怎么构造这个东西,由于要求字典序最大我们从大到小来考虑元素,把 \(S\) 从大到小排序。令 \(ans_i\) 表示构造出来的 \(a_i\)\(S\) 的第 \(ans_i\) 个元素。那么 \(ans_i = \max(ans_{i/k} + 1)\),其中 \(k\)\(i\) 的一个质因子。时间复杂度 \(O(n\sqrt n)\)

CF2203/Edu 187

一万年前打的。

C Test Generator

这个题不会也是这辈子有了。

容易想到对 \(m\) 做二进制分解,这样只有 \(2^{p_1},2^{p_2} \cdots 2^{p_n}\) 是能用的。记最高位为 \(p_1\),最低位为 \(p_n\)。那么只有 \(2^{p_n} \mid s\) 的时候才有解。

考虑接下来咋做。对 \(s\) 进行二进制分解。考虑二分答案 \(x\)。那么对应 \(s\)\(m\) 的每一位,如果某一位 \(s\) 需要但 \(m\) 没有,就需要把 \(m\) 这一位的贡献下放。具体看代码:

bool check(ll x)
{
//	cout << "check " << x << '\n'; 
	ll Rem = 0; 
	for (ll i = 60; ~i; -- i )
	{
		ll A = (m >> i) & 1; 
		ll B = (s >> i) & 1; 
		if (B) ++ Rem; 
		if (A) Rem = max(0ll, Rem - x); 
		Rem <<= 1; 
//		if (x < 10 && i < 10) cout << i << ' ' << Rem << '\n'; 
	}
	return Rem == 0; 
}

D Divisibility Game

这个题不是弱智吗?

显然 \(b\) 中只存在三种数。一种是只有 Alice 能拿,一种只有 Bob 能拿,一种两人都能拿。

双方最优的策略显然就是先拿公共的。三种数的个数可以用类似欧拉筛做。预处理出每个数因子的个数即可。

for (ll i = 1; i <= n + m; ++ i )
{
	for (ll j = i; j <= n + m; j += i )
		D[j] += C[i]; 
}

CF2245

B Delete and Concatenate

大战 1h 落败,真神了。

首先考虑一种合法的操作序列:我们不断做操作 \(2\)。记 \(k = \lceil \frac{n}{2} \rceil\)。那么我们进行了 \(k\) 次操作,得到了 \(a\) 中前 \(k\) 大的元素的贡献。容易证明这是答案的下限。

问题在于,考虑 \(a\) 中满足 \(a_i - c > 0\) 数量较多的情况,记这个数量为 \(p\)。那么这些元素是有正贡献的,我们却用操作 \(2\) 浪费掉了。那么只取前 \(\max(k, p)\) 大的元素贡献即可。做完了。

D1 Construct an Array (Easy Version)

显然可以得到每个数 \(\ge 0\)\(<0\)。然后对于一个限制 \(a_i+a_j \ge 0\),判掉 \(a_i,a_j\) 符号一样的情况,不妨令 \(a_i < 0,a_j \ge 0\),那么有 \(|a_i|\le a_j\)。同理对于限制 \(a_i+a_j < 0\),需要 \(|a_i|>a_j\)。那么将较小数的编号向较大数连边,如果有环就爆掉了。(由于符号不同不可能存在所有数相等的情况),跑完 topo 就是简单构造。

ABC441

D Paid Walk

有意思。赛时不会。

考虑题目中给的出度 \(\le 4\)。以及 \(L \le 10\)。直接暴力即可。总的时间复杂度 \(O(4^{10})\)。轻松通过。

E A > B substring

手刃了。树状数组板子。

考虑怎么做到线性?

原来的做法不太能做。考虑递推。由第 \(i - 1\) 位的答案递推第 \(i\) 位的答案。考虑 \(S_i\)

  • \(S_i = 1\)。此时对于前面满足条件的区间我们都满足。同时前面 \(0,1\) 相等的区间也满足。
  • \(S_i = 0\)。此时前面 \(1\)\(0\)\(1\) 的区间不满足。其余前面满足的区间都满足,扣掉就好了。

那么就是线性的。

F Must Buy

好题啊。

只要对于每个物品,求出选它 / 不选它能达到的最大价值。

这个可以分别做前缀 / 后缀背包。

ABC443

D Pawn Line

神秘贪心结论题。

对于每个棋子,尽量地不去动它能使操作数最小。

\(a_i\) 为棋子 \(i\) 的初始位置,\(b_i\) 为最终位置。只需最大化 \(\sum b_i\)

考虑一下约束。需要使得 \(b_i \le a_i\),$b_i \le b_{i+1} + 1 $ 且 \(b_{i+1} \le b_i + 1\)

于是 \(b_i = \min(a_i,b_{i-1}+1,b_{i+1}+1)\)。左到右跑使得 \(b_i \le b_{i-1} + 1\),右到左跑维护后者即可。

线性。

E Climbing Silver

简单题。每个点按题意暴力地扩展。判断某个墙是否能被爆破只需维护那一列的所有墙。如果在尾端就能并弹出即可。

\(O(n^2)\)

F Non-Increasing Number

板子。bfs 队列里放余数和最后的数字。扩展是简单的。注意记忆化一下。那就是 \(O(10n)\) 的。

可以证明只要不是 \(10\) 的倍数总是有解的。

ABC444

D Many Repunit Sum

差分一下然后处理一下进位就好了。

E Sparse Range

妙妙题。一开始看错题想了挺久的。

注意到对于每个左端点 \(l\),与它满足条件的右端点 \(r\) 总是一段的。也就是说,找到最后一个满足条件的 \(r\),有 \([l, r], [l, l + 1], \cdots, [l, r]\) 均满足条件。

于是可以双指针,每次加入一个数时用 set 判一下是否满足条件即可。\(O(n \log n)\)

ABC461

D Count Subgrid Sum = K

无敌了,还以为是什么神秘单调性题目,结果 \(O(n^3\log n)\) 直接过了。无敌了。

具体就是枚举左下角的点,再确定左上方点的 \(y\) 值,这样二分 \(x\) 即可。二分得到一段 \(x\),使得和为 \(K\)。简单计数。

双指针也是容易的。只需要维护 \(\le K\)\(\ge K\) 的位置,这个容易单调维护。于是做到 \(O(n^3)\)

E E-liter

ds 题。做了很久才过,大失败。

考虑操作 \(1\),横着涂一行黑的会改变什么。如果是第一次涂这一行,贡献显然就是 \(n\)。但是如果不是呢?不妨记上一次涂这一行的时刻为 \(j\),当前时刻为 \(i\)。那么时刻 \(j \sim i\) 中有多少列被涂白了,这一次操作就会把它们变成黑的。贡献就是这个列数。

那么问题转化为求时刻 \(j \sim i\) 中,有多少列被涂白了,注意要去重。操作 \(2\) 的贡献也是同理的。\(j\) 是很好维护的,维护第 \(p\) 行,第 \(q\) 列上一次涂的时间 \(r_{p},c_{q}\) 即可。那么可以把询问序列离线下来然后扫描线用树状数组算。

F Total Product is N

这个题,有点牛福的。
查表得知 \(n\) 的因子个数最大值为 \(2304\),记 \(D = 2304\)。考虑 dp。
按因子从小到大选,然后因为不同顺序的序列要算多次,最后还要乘上选的数个数的阶乘。记 \(f_{i,j,k}\) 表示前 \(i\) 个因子,选了 \(j\) 个,得到的积为 \(k\) 的答案,\(g_{i,j,k}\) 表示方案数。这里的 \(k\) 是一个映射。考虑怎么转移:
判断第 \(i\) 个因子 \(d_i\) 是否满足 \(d_i \mid k\)

  1. 不是。此时不能选,\(f_{i,j,k} = f_{i-1,j,k}\)\(g_{i,j,k} = g_{i-1,j,k}\)
  2. 是。考虑选不选,\(f_{i,j,k} = f_{i-1,j,k} + f_{i-1,j-1,\frac{k}{d_i}} + d_i \times g_{i-1,j-1,\frac{k}{d_i}}\)\(g_{i,j,k} = g_{i-1,j,k} + g_{i-1,j-1,\frac{k}{d_i}}\)

那么做完了。由于 \(i\)\(k\)\(D\) 的量级,\(j\)\(\log n\) 的量级,时间复杂度就是 \(O(D^2\log n)\)

ABC467

E Adjacent Sums (hard)

ABC 史上最难 E 有感觉吗。

确定首位就能推出序列。记 \(A_1\) 不变时得到序列为 \(c_i\)
答案 \(f(0) = 0 + \sum_{i=2}^n (c_i - a_i) + [c_i < a_i]m\)
考虑增量 \(\Delta\),答案 \(f(\Delta) = \Delta + \sum_{i=2}^n(c'_i - a_i) + [c'_i < a_i]m\)。考虑 \(\Delta\) 变化时有什么影响,在 \(\Delta - 1 \to \Delta\) 的时候,显然奇数位的 \(c_i\) 加了 \(1\),偶数位的 \(c_i\) 减了 \(1\),贡献为 \(-1/1\)。然后对于后者的贡献,考虑分讨:

  • 偶数位。对于 \(c_i \ge a_i\) 的部分,对 \(f(c_i - a_i + 1)\)\(m\) 的贡献,这意味着 \(c_i\) 变成 \(< a_i\) 了。然后对于 \(c_i < a_i\) 的部分,对 \(f(m - (a_i - c_i) + 1)\)\(m\) 的贡献。
  • 奇数位也是同理,直接给结论:对于 \(c_i < a_i\) 的部分,对 \(f(a_i-c_i)\)\(-m\) 的贡献。对于 \(c_i \ge a_i\) 的部分,对 \(f(m - (c_i-a_i))\)\(-m\) 的贡献。

注意上述对奇数位的讨论是不包括 \(1\) 的。
这样做其实是因为我们并没有真正对 \(c_i\)\(c_i \to (c_i + 1/-1) \bmod m\) 这个操作,\(c_i\) 一直在增大或者减小,前者 \(c_i-a_i\) 的贡献实际上是不对的,包含了后面有关 \(m\) 的贡献。我们实际上是把两者合在一起来考虑了。
那么至多 \(2n\) 个贡献点,用 map 维护即可。时间复杂度 \(O(n\log n)\)

F Email Scheduling Optimization

考虑排序交换,贪心地得到结论,优先做 \(b\) 较大的。
写出答案就是 \(\max(\sum_{j=1}^i a_j + b_i)\)。考虑怎么用数据结构维护这个东西。显然可以以 \(b_i\) 做下标用 sgt 维护贡献,具体把询问离线下来,把所有有用的 \(b_i\) 离散化就是对的。然后要注意需要维护区间是否有数,不能让当前不存在的 \(b_i\) 产生影响。

貌似可以暴力分块也是能过的。具体对 \(b_i\) 分块,块内暴力维护。修改和查询都是 \(O(\sqrt n)\) 的。

CF2247

B Yet Another Constructive

补一个 \(k > m\) 无解的证明。
考虑证明由于 \(a_i \ge 1\),任意一个长度为 \(m\) 的序列里,总有一个子数组的和 \(\bmod m = 0\)
考虑数组的前缀和,有 \(m + 1\) 个前缀和,而这 \(m+1\) 个前缀和 \(\bmod m\) 至多只有 \(m\) 种取值,必定存在两个前缀和关于 \(m\) 同余,那么这就可以凑成一个一个合法的子数组,证明完毕。

D1 XOR Sorting (Easy Version)

神秘。记 \(k\) 的最高位为 \(B\),有 \(2^B \le k < 2^{B+1}\)
然后一个神秘的结论是,我们把序列分成长度为 \(2^{B+1}\) 的若干段,这样每一段就是:

  • \([0,2^{B+1}-1]\)
  • \([2^{B+1},2\times 2^{B+1}-1]\)
  • \([2 \times 2^{B+1}, 3 \times 2^{B+1}-1]\)
  • ......

以此类推,可以发现块内的下标只有低 \(B\) 位可能不同,其他位是相同的,也就是任意块内下标的异或总是 \(< 2^{B+1}\)
那么 \(k\) 不取 \(2\) 的幂次是不优的,这样就证明了 \(k\) 一定是 \(2\) 的幂次。那么暴力枚举 \(k\) 每次线性扫一遍序列判断即可。时间复杂度 \(O(n\log n)\)

D2 XOR Sorting (Hard Version)

带修了咋办,注意到这个东西很像线段树。我们把序列长度补成 \(2^k\),然后线段树上维护区间答案,也就是区间对应的 \(k\)。在合并的时候取两个儿子 \(k\) 的最大值。但是如果左儿子权值 max 大于右儿子权值 min,\(k\) 只能为区间长度。

ARC225

A Four Coloring

无敌了。

把原来的条件加强,对于任意的点对我们都需满足条件。构造出映射数组 \([2,4,1,3]\)

B Independent Nim

纸张博弈。

考虑长度为 \(2\) 的为 \(1\) 的连续段,显然先手必败。
然后考虑原序列中若干个为 \(1\) 的连续段,你发现先手总是可以通过一次操作来使得剩下的全是若干个长度为 \(2\) 的连续段(除非原来就已经是这个状态)。那么判掉这个状态即可。

C K Spanning Tree

不妨把所有的 \(0\) 边先连上,然后可以得到必需的 \(1\) 边的数量。
把必需的 \(1\) 边连上,由于此时把 \(0\) 边全连上肯定可以得到一棵生成树,于是不断加 \(1\) 边直到 \(k\) 条,容易知道此时把 \(0\) 边全加上可以得到一个合法的解。注意加边是指如果两点不联通才加。

也可以考虑 P2619,随机赋权即可。

D Gap Swap (easy)

不考虑已经归位的元素。那么剩下的元素做一遍冒泡显然是对的,这样每个独立的点都可以一步步走到自己原来的位置,没有额外花费。同时一次操作可以让两个相反方向的点走,于是距离还要乘上 \(\frac{1}{2}\)

ABC468

F Chmax

注意到 \(x,y\) 肯定有一个是前缀最大值。不妨记 \(x\) 是,有 \(x > y\)
你考虑当前这个数,假设这个数是前缀最大值,你思考要给 \(x\) 还是 \(y\)。显然是 \(x\),不然你只能取后面前缀最大值的贡献。于是所有的前缀最大值都给了 \(x\),剩下的数跑一遍 LIS 就是对的。

ABC469

D The Big Two

枚举度数 \(d_u + d_v \ge m\) 的点对即可,注意要去除重边以及 \((u,v)\)
当然可以观察到的是,\(x,y\) 中必然有个点的度数 \(\ge \frac{m}{2}\),然后因为度数 \(\ge \frac{m}{2}\) 的点只有常数个,直接枚举就是对的。

E Pro Exam Eligibility

二分就做完了。

F GCD Maximum Spanning Tree

经典的 trick 是枚举 gcd,然后把边权等于 gcd 的边放进图里判断是否连通,同时计算贡献。这是因为 gcd 更大的边我们肯定是贪心地要的。
那么用并查集维护连通性就是对的,时间复杂度 \(O((n+V)\log V)\) 还要乘上并查集的复杂度。

然后考虑 这个题,把做法套过来只能过 \(60\)。考虑优化,gcd 只用从 \(\frac{n}{2}\) 开始枚举,然后在对 gcd 加边的时候,你只需要枚举编号为某个质数 \(p*\gcd\) 的点。能显著减小枚举的次数,然后就过了。

相同的 trick 再考虑 这个题。同样是枚举 gcd,把边权为 gcd 的倍数的边加进图里,求一遍树上直径就是对的。

posted @ 2026-06-14 12:11  RainyRadio  阅读(7)  评论(0)    收藏  举报