Problem A. 新太阳睡觉中心
Input file: standard input
Output file: standard output
Time limit: 2 seconds
Memory limit: 512 megabytes
’Cause morning rolls around, and it’s another day of sun!
但是作为一个睡瘾患者,肖恩经常睡觉睡个半天,因此,当他醒来时,他甚至记不清今天是星期几。
所以从某一天开始,他开始进行记录:每次他醒来的时候,他就会写下一个数字,表示此时外面是否有阳光。如果有,他会写一个 1;否则,他会写一个 0。在完成记录后,还没等太阳下山,或是太阳升起,他又再次入睡。假设每次肖恩醒来时,他看到的要么是阳光,要么是月光,但不会同时看到两者。
这些记录下来的数字实际上形成了一个长度为 n 的数组:[a1*, a2, . . . , an] (∀1 ≤ i ≤ n, 0 ≤ ai ≤ 1),其中ai* 表示肖恩写下的第 i 个数字。
然而,随着时间的推移,一些写下的数字变得模糊不清,你无法判断它是 1 还是 0。如果有 k 个数字无法识别,则可能有 $2^k$ 种不同的数组。
对于每个可能的数组,你都可以依据这个数组计算肖恩看到阳光的最小天数。如果将可能的不同数组的最小天数结果相加,得到的结果如何呢?由于答案可能很大,请将结果关于 998 244 353 取模后输出。
Input
每组测试包含多个测试用例。第一行是测试用例的数量 T (1 ≤ T ≤ $10^4$ )。
每个测试用例由两行组成。
第一行包含一个整数 n (2 ≤ n ≤ 5 × $10^5$ ),表示笔记的数量。
第二行包含 n 个整数 a1*, a2, . . . , an* (−1 ≤ ai ≤ 1),表示每个记录下来的数字。只有当 ai = −1 时,数字是未知的。
可以保证单组测试中, $\sum$n 不会超过 5 × $$10^5$$。
Output
对于每个测试用例,输出 1 个整数 — 不同数组的最小天数求和后,对 998 244 353 取模的结果。
Example
standard input
1 | 3 |
standard output
1 | 2 |
Note
在第一个测试用例中,当肖恩记录第一个和第三个数字 1 时,他看到的阳光一定是两个不同的天的。
在第二个测试用例中,肖恩从未看到阳光,因此答案是 0。
在第三个测试用例中,数组可能是 [1*,* 1*,* 1] 或 [1*,* 0*,* 1]。如果数组是 [1*,* 1*,* 1],那么这些数字可能都是同一天被记录下来的,因此结果是 1。如果数组是 [1*,* 0*,* 1],那么与第一个测试用例一致,结果为 2。将两种情况的答案求和,结果是 1 + 2 = 3。
题解:
“最小阳光天数” 的总和相当于:所有位置在所有可能数组中作为 “新阳光段起始点” 的次数之和。
而能作为起始点的位置i需满足:
- 该位置的值为 1(或 - 1 替换为 1);
- 前一个位置
i-1的值不为 1(或 - 1 替换为 0)(若i=0则无此限制)。
累加每个位置作为起始点的次数即为答案。
1. 预处理
由于 - 1 可替换为 0 或 1,总共有$2^k$种可能数组(k是 - 1 的数量)。预计算v[i] = $2^i$ mod 998244353,可以快速得到当前位置的贡献的大小。
2. 遍历每个位置计算贡献
对每个位置i,计算起始点次数:
1.i=0(第一个元素)
只需满足 i 位置为 1 :
- 若原数组
a[0] = 1:所有k个 - 1 可任意替换,贡献为v[k]; - 若原数组
a[0] = -1:需将其固定为 1,剩余k-1个 - 1 可任意替换,贡献为v[k-1](若k≥1); - 若原数组
a[0] = 0:无法作为起始点,贡献为 0。
2.i>0(非第一个元素)
需满足 i 位置为 1 且 i-1不为 1 :
- 若前一个位置
a[i-1] = 1:无法作为起始点,贡献为 0; - 否则,计算 “固定 - 1 的数量”:
- 若
a[i] = -1:需固定为 1(+1); - 若
a[i-1] = -1:需固定为 0(+1);
- 若
- 剩余可自由替换的 - 1 数量为
k - 固定数,贡献为v[剩余数](若剩余数≥0)。
代码
1 |
|
时间复杂度:O(Tn)
Problem B. 位完美
Input file: standard input
Output file: standard output
Time limit: 2 seconds
Memory limit: 512 megabytes
军蚁正在为一场残酷的战争做准备,但事情变得比他们想象的更复杂。
队伍中有 n 只军蚁。最初,每只军蚁 i (1 ≤ i ≤ n) 的力量为 ai。
然而,在战争期间会发生一些奇怪的事情:一股神秘力量会随机选择一个二元组 (i, j) (1 ≤ i < j ≤ n),
而选择后,蚂蚁 i 和蚂蚁 j 会消失,并且一只新蚂蚁会替代它们神奇地出现,其力量为 ai ⊕ aj,即 ai和 aj 的按位异或(XOR)。
这种情况非常罕见,在整个战争中最多只会发生一次。
蚂蚁们认为整个队伍的总力量为$\sum_{i=1}^{n}$ $2^{a_i}$ ,如果那件”奇怪的事”永远不会减少军队的整体力量,则这个军队被认为是 位完美 的。
由于忙于练兵,蚂蚁们没有足够的时间来检查队伍是否位完美。你能帮帮他们吗?可能会有 T 支不同的军队。
Input
每组测试包含多个测试用例。第一行包含测试用例的数量 T (1 ≤ T ≤ 105 )。
每个测试用例由两行组成。
第一行包含一个整数 n (2 ≤ n ≤ 5 × 105 ),表示队伍中蚂蚁的数量。
第二行包含 n 个整数 a1*, a2, . . . , an* (1 ≤ ai ≤ 1018),表示每只蚂蚁的力量。
保证在单组测试中, Pn 不会超过 5 × 105。
Output
对于每个测试用例,如果该军队是 位完美 的,则输出 YES,否则输出 NO。你可以以任意大小写打印答案。
Input
1 | 3 |
Output
1 | YES |
Note
在第一个测试用例中,如果两只蚂蚁合并,由于 3 ⊕ 5 = 6,整个队伍的总力量从 $2^3$ + $2^5$ = 40 变为
$2^6$ = 64,因此该事件不会减少总力量。所以该队伍是位运算完美。
题解
问题的核心在于:任意一对蚂蚁合并后阵容的总强度不会降低。
- 重复力量降低:使用
set存储蚂蚁的力量值,检查是否存在重复的力量值。如果存在重复,那么合并后一定会降低阵容的总强度,故直接输出 “NO”。 - 枚举:对于每一对不同的蚂蚁
(i, j),计算合并后的力量值a[i] ^ a[j]。如果合并后总强度降低,则输出 “NO”。 - 结果:如果所有蚂蚁对合并后总强度都不降低,则输出 “YES”。
代码
1 |
|
时间复杂度
- 时间复杂度: O($Tn^2$)