0%

题目大意

这是魔法,不是戏法!(It’s Magic, Not a Trick!)

时间限制:C/C++/Rust/Pascal 2 秒,其他语言 4 秒
空间限制:C/C++/Rust/Pascal 1024 MB,其他语言 2048 MB

“呃……真麻烦,不过真正的魔法师是不会放弃的。”

自称"超高校级的魔法师"的梦野秘密子在自己面前摆了一排共 nn 个附魔护符。第 ii 个护符最初蕴含 aia_i 单位魔力,且每个 aia_i 都是正整数。最近她研读了一本积满灰尘的古老魔导书,破译出了一个以极为特殊的方式操纵魔力的咒语。

每施放一次咒语,她必须严格按顺序执行以下两步:

  1. 注魔:选择任意一个护符,向其中注入恰好 11 单位自身的魔力,使该护符的魔力增加 11

  2. 释放:选择任意一个在注魔完成之后魔力至少为 xx 的护符,爆发出耀眼的光芒,从该护符中消耗恰好 xx 单位魔力,使其魔力减少 xx。两步可以选择同一个护符,也可以选择不同的护符,咒语在这一点上是灵活的。

但有一条关键限制:如果注魔完成之后不存在魔力至少为 xx 的护符,则释放无法进行。此时整个咒语直接失效,什么都不会发生,她试图注魔的那个护符的魔力也保持不变。

只要每一次尝试都能成功、且所有护符的魔力始终保持非负,秘密子就可以任意多次地施放这个咒语。她好奇自己法术的极限:通过选择每次注魔与释放的位置,所有护符剩余魔力之和最小可能是多少?

比起自己算术,她更想去睡一觉,于是她向你——她可靠的助手——求助。由于答案可能很大,你只需要输出答案对 998244353998244353 取模的结果。

每个测试点包含多组测试数据。

第一行包含一个整数 tt1t1041 \le t \le 10^4),表示测试数据的组数。接下来是各组测试数据的描述。

每组测试数据的第一行包含两个整数 nnxx1n21051 \le n \le 2 \cdot 10^51x1091 \le x \le 10^9)。

第二行包含 nn 个整数 a1,a2,,ana_1, a_2, \ldots, a_n1ai10181 \le a_i \le 10^{18})。

保证所有测试数据中 nn 的总和不超过 21052 \cdot 10^5

对于每组测试数据,输出一个整数——所有护符剩余魔力之和的最小可能值对 998244353998244353 取模的结果。

1
2
3
4
5
6
7
3
3 3
1 1 1
1 4
3
4 10
30 8 7 6
1
2
3
3
0
6

第一组数据x=3x = 3,所有护符魔力均为 11。无论向哪个护符注魔,注魔后魔力最大也只有 2<32 < 3,无法进行释放,因此秘密子一次咒语也无法施放,剩余魔力之和为 1+1+1=31 + 1 + 1 = 3

第二组数据:只有一个护符,魔力为 33x=4x = 4。对该护符注魔得到 44,再对它自身释放,魔力变为 00。此后无法继续施放,答案为 00

第三组数据x=10x = 10,初始魔力为 [30,8,7,6][30, 8, 7, 6]。可以按如下方式施放 55 次咒语:

次数 注魔对象 释放对象 操作后的魔力序列
1 22 个(898 \to 9 11 个(302030 \to 20 [20,9,7,6][20, 9, 7, 6]
2 22 个(9109 \to 10 11 个(201020 \to 10 [10,10,7,6][10, 10, 7, 6]
3 33 个(787 \to 8 11 个(10010 \to 0 [0,10,8,6][0, 10, 8, 6]
4 33 个(898 \to 9 22 个(10010 \to 0 [0,0,9,6][0, 0, 9, 6]
5 33 个(9109 \to 10 33 个(10010 \to 0 [0,0,0,6][0, 0, 0, 6]

此时剩余魔力之和为 66,且无法再继续施放咒语,因此答案为 66

思路讲解

初始放电次数:

1
2
3
4
5
6
7
8
9
10
// ---------------- 3. 提取“免费放电次数” = “初始注入预算” ----------------
// cnt:光靠已有能量就能完成的放电次数 sum(a_i / x)。
// 这 cnt 次施法各自附带的那个 +1 可以任意投放,所以 cnt 同时就是可支配的预算。
// 取模后 a[i] 只保留余数 r_i ∈ [0, x-1]。
i128 cnt = 0;
for (int i = 0; i < n; i++)
{
cnt += a[i] / x;
a[i] %= x;
}

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (int i = 0; i < n; i++)
{
// 把这个符从 r_i 抬到 x 需要 x - r_i 点,
// 其中 1 点由“放它自己的那次施法的注入”免费提供,
// 其实这个减少了题目难度,因为可以直接融入进 cost 里面,不用再单独拿出来算啊
// 所以真正要从预算里掏的是 x - r_i - 1 点。
// 特别地,r_i == x - 1 时代价为 0:即使预算为空也能白嫖一次施法。
i128 cost = x - a[i] - 1;

if (cost <= cnt)
{
cnt -= cost; // 花掉预算
a[i] = 0; // 这个符被打到 0
round++; // 多出一次成功施法
}
// 由于 a 已降序 → cost 单调不减,而 cnt 单调不增,
// 因此一旦买不起,后面全都买不起,这里其实可以直接 break。
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ---------------- 5. 用剩余预算反复“复用零符” ----------------
// 重新降序排序:被买下的都变成 0 了,排完之后 a[0] 是剩下的最大余数。
// a[0] == 0 表示所有符都已归零。
sort(all(a), greater<>());

if (a[0] == 0) // a[0] == 0 表示所有符都已归零。
{
// 下面就是计算朴素情况啊
// 全零之后想再多施一次法,只能挑一个 0 号符:
// 从预算掏 x-1 点把它填到 x-1,再靠本次施法自带的 +1 补满 x 然后放电。
// 所以此后每一次施法的净代价固定为 x - 1,能买几次就买几次。
if (cnt >= x - 1)
{
i128 d = cnt / (x - 1);
cnt -= (x - 1) * d;
round += d;
}
// 注:若 a[0] != 0,说明它没被买下,即 x - a[0] - 1 > cnt,
// 而 x - a[0] - 1 <= x - 2 < x - 1,故必有 cnt < x - 1,
// 这个分支本来也会得到 d = 0 —— 判断是冗余的,保留只为语义清晰。
}
1
2
3
4
// ---------------- 6. 输出 S - (x-1) * R ----------------
// round 最大约 1e23,(x-1) % MOD < 1e9,乘积约 1e32,仍在 i128 范围内。
// 先减可能变负,故 +MOD 再取模。
cout << (sum - (x - 1) % MOD * round % MOD + MOD) % MOD << "\n";

AC代码

https://ac.nowcoder.com/acm/contest/view-submission?submissionId=84457244

心路历程(WA,TLE,MLE……)

题目大意

世界树的裂隙

时间限制:C/C++/Rust/Pascal 4 秒,其他语言 8 秒
空间限制:C/C++/Rust/Pascal 1024 MB,其他语言 2048 MB
Special Judge,64bit IO Format: %lld

在月球上,篝一直研究着一份浩繁的可能性集合。她用一种极度压缩的语言讲述自己的发现:寥寥数语所承载的信息,就足以压垮一个普通人的心智。

孝太郎不愿认输,一次次动用自己加速思维的能力去追赶她的讲解。这样的尝试失败了太多次,于是篝决定在继续讲下去之前,先测一测他的反应速度。当然,"把话说得简单些"从来不在她的选项之内。

这一次,篝取出了一棵有 nn 个顶点的世界树,顶点编号为 11nn。这棵树是无向、无权的。

每次询问给出两个顶点 uuvv。篝会暂时删去 uuvv 的唯一简单路径上的所有边,此时世界树会分裂成若干个连通块,构成一个森林。

一个连通块的直径定义为其中任意两点之间距离的最大值,其中距离指两点间路径上的边数。特别地,只含一个顶点的连通块,其直径为 00

对于每次询问,孝太郎需要求出所有连通块直径之和

各次询问相互独立:每次询问结束后,所有被删去的边都会恢复原状,然后才进行下一次询问。特别地,若 u=vu = v,则该路径上不含任何边,世界树保持不变。

第一行包含两个整数 nnqq1n,q21051 \le n, q \le 2 \cdot 10^5)。

接下来 n1n - 1 行,每行两个整数 aia_ibib_i1ai,bin1 \le a_i, b_i \le n),表示顶点 aia_ibib_i 之间有一条无向边。保证这些边构成一棵树。

接下来 qq 行,每行两个整数 uiu_iviv_i1ui,vin1 \le u_i, v_i \le n),表示一次询问。

对于每次询问,输出一行一个整数,表示删去对应路径上的边之后,所有连通块的直径之和。

1
2
3
4
5
6
7
8
9
10
11
12
7 5
1 2
2 3
3 4
3 5
5 6
5 7
1 4
6 7
3 3
2 5
1 7
1
2
3
4
5
2
3
4
4
2

image

image

image

样例中的树形态如下:边集为 {(1,2),(2,3),(3,4),(3,5),(5,6),(5,7)}\{(1,2),(2,3),(3,4),(3,5),(5,6),(5,7)\}

  • 询问 11u=1,v=4u = 1, v = 4 路径为 12341 \to 2 \to 3 \to 4,删去边 (1,2),(2,3),(3,4)(1,2),(2,3),(3,4)。剩余连通块为 {1}\{1\}{2}\{2\}{4}\{4\}{3,5,6,7}\{3,5,6,7\},直径分别为 0,0,0,20, 0, 0, 2,总和为 22

  • 询问 22u=6,v=7u = 6, v = 7 路径为 6576 \to 5 \to 7,删去边 (5,6),(5,7)(5,6),(5,7)。剩余连通块为 {6}\{6\}{7}\{7\}{1,2,3,4,5}\{1,2,3,4,5\},直径分别为 0,0,30, 0, 3(如 1144 之间),总和为 33

  • 询问 33u=3,v=3u = 3, v = 3 路径不含任何边,整棵树保持不变,其直径为 44(如 1166 之间),总和为 44

  • 询问 44u=2,v=5u = 2, v = 5 路径为 2352 \to 3 \to 5,删去边 (2,3),(3,5)(2,3),(3,5)。剩余连通块为 {1,2}\{1,2\}{3,4}\{3,4\}{5,6,7}\{5,6,7\},直径分别为 1,1,21, 1, 2,总和为 44

  • 询问 55u=1,v=7u = 1, v = 7 路径为 123571 \to 2 \to 3 \to 5 \to 7,删去边 (1,2),(2,3),(3,5),(5,7)(1,2),(2,3),(3,5),(5,7)。剩余连通块为 {1}\{1\}{2}\{2\}{3,4}\{3,4\}{5,6}\{5,6\}{7}\{7\},直径分别为 0,0,1,1,00, 0, 1, 1, 0,总和为 22

思路讲解

AC代码

心路历程(WA,TLE,MLE……)

题目大意

题目描述

Bob 正在为学校的一场模拟战斗设计队形,参与者扮演潘普洛纳战役中的士兵。

一个队形是一个 r×cr \times c 的网格,其中恰好有 mm 个格子里站着士兵。敌方每消耗一发炮弹,可以进行如下操作:

  • 选择某一行或某一列,消灭该行或该列中的所有士兵

定义一个队形的韧性为消灭其中所有士兵所需的最少炮弹数。

给定 r,c,m,kr, c, m, k,请构造出任意一个韧性恰好等于 kk 的队形,或者报告无解。你需要回答同一个文件中的 TT 组测试数据。

输入格式

第一行包含一个整数 TT,表示测试数据的组数。

接下来是每组测试数据的描述,每组数据占一行,包含四个用空格分隔的整数 r,c,m,kr, c, m, k

输出格式

对于每组测试数据,若无解,输出一行 NO;否则输出一行 YES

若输出 YES,则接下来还需输出一个 r×cr \times c 的网格,即输出 rr 行,每行包含一个长度为 cc 的字符串。网格中只能包含字符 .#,分别表示空地和站有士兵的格子;注意其中恰好应有 mm 个字符为 #

若存在多组可行解,输出任意一组均可。

数据范围与评分

对所有子任务:

0T1500,1r,c25,1mrc,1k1090 \leq T \leq 1500,\quad 1 \leq r, c \leq 25,\quad 1 \leq m \leq rc,\quad 1 \leq k \leq 10^9

子任务 分值 限制
1 40\mathbf{40} m=km = k
2 30\mathbf{30} m=2km = 2k
3 20\mathbf{20} m=3m = 3
4 10\mathbf{10} 无额外限制

样例

1
2
3
2
7 8 11 4
9 6 2 10
1
2
3
4
5
6
7
8
9
YES
........
...#....
#..#...#
#....#.#
...##.#.
........
...#....
NO

对于第一组数据,可以验证所有士兵能够用 44 次操作被清除:选择从上往下的第三、四、五行,以及从左往右的第四列。同时可以说明无法用 33 次操作完成,因此该队形的韧性为 44

对于第二组数据,无法构造出满足要求的队形。

思路讲解

AC代码

心路历程(WA,TLE,MLE……)

题目大意

翻牌配对

时限 2000 ms,内存 1024 MB。

给定整数 N,LN, L 以及 NN 个两两不同的整数 A1,A2,,ANA_1, A_2, \dots, A_N

桌上共有 2N2N 张牌,每个数值 AiA_i 恰好写在其中两张牌的正面上,牌的背面没有任何信息。

初始时把所有牌随机洗乱后背面朝上摆放。等价地说:设 BB 是把序列 (A1,A1,A2,A2,,AN,AN)(A_1, A_1, A_2, A_2, \dots, A_N, A_N) 均匀随机打乱后得到的长度为 2N2N 的序列,则第 ii 张牌正面的数字为 BiB_i

玩家知道所有的 AiA_i,但最初不知道任何 BiB_i。一旦某张牌 ii 被翻开,玩家就会永久记住 BiB_i 的值。

游戏开始时,生命值为 LL,得分为 00,尚未被移除的牌的下标集合为 S={1,2,,2N}S = \{1, 2, \dots, 2N\}。玩家在任何时刻都知道当前的生命值、得分和集合 SS

重复执行以下步骤,直到生命值变为 00 或者 SS 为空:

  1. 玩家根据当前已知信息,从 SS 中选择一张牌 ii 并翻开,获知 BiB_i

  2. 玩家根据当前已知信息(包括刚获知的 BiB_i),从 S{i}S \setminus \{i\} 中选择一张牌 jj 并翻开,获知 BjB_j

  3. Bi=BjB_i = B_j,则把 i,ji, jSS 中移除,并把得分增加 BiB_i

  4. BiBjB_i \neq B_j,则把这两张牌翻回背面,并把生命值减少 11

玩家以最大化最终得分的期望值为目标采取最优策略。请求出游戏结束时的期望得分。

输入从标准输入按以下格式给出:

第一行两个整数 NNLL

第二行 NN 个整数 A1,A2,,ANA_1, A_2, \dots, A_N

输出一行一个实数,表示最优策略下游戏结束时的期望得分。答案与标准答案的绝对误差或相对误差不超过 10510^{-5} 即视为正确。

  • 1N2001 \leq N \leq 200

  • 1L2001 \leq L \leq 200

  • 1A1<A2<<AN1051 \leq A_1 < A_2 < \dots < A_N \leq 10^5

  • 所有输入值均为整数。

1
2
3 2
1 2 3
1
3.8666666667

游戏可能按如下方式进行。为了区分这六张牌,分别称它们为 ABCDEF

游戏以生命值 22、得分 00 开始。

翻开卡牌 A,上面写着 33
翻开卡牌 B,上面写着 22
因为数字不同,把两张牌翻回背面,生命值减少 11,变为 11

翻开卡牌 C,上面写着 33
翻开卡牌 A,上面写着 33
因为数字相同,把这两张牌移出桌面,得分增加 33,变为 33

翻开卡牌 D,上面写着 11
翻开卡牌 E,上面写着 22
因为数字不同,把两张牌翻回背面,生命值减少 11,变为 00

生命值变为 00,游戏结束,最终得分为 33

注意,在上述过程中刚翻开卡牌 C 之后,玩家可以利用「卡牌 C 正面写着 33」这一信息,选择翻开另一张已经知道写着 33 的卡牌 A

1
2
5 2
2 3 5 7 101
1
17.8560846561
1
2
20 10
10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200
1
770.7122293087

思路讲解

AC代码

心路历程(WA,TLE,MLE……)

题目大意

D - Inverse and Swap

时间限制:2 秒 / 内存限制:1024 MiB

分值:400400

给定一个 (1,,N)(1, \dots, N) 的排列 P=(P1,,PN)P = (P_1, \dots, P_N)

请依次处理 QQ 个询问,询问有以下两种:

  • 1 x y:交换 PxP_xPyP_y 的值。

  • 2:构造满足以下条件的 (1,,N)(1, \dots, N) 的排列 P=(P1,,PN)P' = (P'_1, \dots, P'_N),并将 P1,,PNP_1, \dots, P_N 的值分别替换为 P1,,PNP'_1, \dots, P'_N。(可以证明满足条件的 PP' 唯一存在。)

    • 对每个满足 1iN1 \leq i \leq N 的整数 ii,都有 PPi=iP_{P'_i} = i

请输出处理完所有询问后 P1,,PNP_1, \dots, P_N 的值。

输入从标准输入给出,格式如下:

1
2
3
4
5
N Q
P_1 P_2 ⋯ P_N
query_1

query_Q

其中 queryq\mathrm{query}_q 表示第 qq 个询问,以下面两种格式之一给出:

1
1 x y
1
2

将处理完所有询问后 P1,,PNP_1, \dots, P_N 的值以空格分隔,输出在一行中。

  • 2N5×1052 \leq N \leq 5 \times 10^5

  • 1Q5×1051 \leq Q \leq 5 \times 10^5

  • (P1,,PN)(P_1, \dots, P_N)(1,,N)(1, \dots, N) 的排列

  • 对于类型 11 的询问,1x<yN1 \leq x < y \leq N

  • 输入中的所有值均为整数

输入

1
2
3
4
5
6
7
5 5
2 1 3 5 4
1 2 4
2
1 2 3
1 3 4
2

输出

1
4 5 2 1 3

说明

每个询问处理完成时,P1,,PNP_1, \dots, P_N 的值如下:

  • 处理完第 11 个询问时,P=(2,5,3,1,4)P = (2,5,3,1,4)

  • 处理完第 22 个询问时,P=(4,1,3,5,2)P = (4,1,3,5,2)

  • 处理完第 33 个询问时,P=(4,3,1,5,2)P = (4,3,1,5,2)

  • 处理完第 44 个询问时,P=(4,3,5,1,2)P = (4,3,5,1,2)

  • 处理完第 55 个询问时,P=(4,5,2,1,3)P = (4,5,2,1,3)

输入

1
2
3
4
5
6
7 4
3 7 5 6 4 2 1
2
2
2
2

输出

1
3 7 5 6 4 2 1

说明

本样例中的 44 个询问均为类型 22,处理完成后 PP 与初始时相同。

输入

1
2
3
4
5
6
7
8
9
10
10 8
7 3 2 4 8 5 10 9 1 6
2
1 4 10
1 6 9
2
1 9 10
1 3 10
2
1 4 6

输出

1
3 10 2 8 6 7 1 5 9 4

说明

本样例包含两种询问混合出现的情况,请按照询问给出的顺序依次处理。

思路讲解

image

那么实际上,排列就是位置和值的对应关系啊至于箭头的方向和哪边是位置,哪边是值,这个其实不是特别重要啊,用一个变量 f 维护一下即可啊。

那么这个叫什么交换操作就只是需要修改一下这个对应关系即可啊,这个就非常简单,你可以理解为我们就是一个无向图啊,然后最后再进行定向即可啊。

当然,还是要注意一下值和位置当前的对应关系啊。

存储的时候,S 和 T都可以看成是一个只有一条出边的有向图邻接表啊,那么实际上,我们存储的就是这个无向图啊。因为无向图就是一条边有两个方向的有向图嘛。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
int mp[2][500005];

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);

int n, q;
cin >> n >> q;

for (int i = 1; i <= n; i++) {
cin >> mp[0][i]; // 位置 i —— 值 mp[0][i]
mp[1][mp[0][i]] = i; // 同一条边,从值那一侧再记一遍
}

int f = 0; // 定向标记

while (q--) {
int op;
cin >> op;

if (op == 2) {
f ^= 1; // 换个方向读,O(1)
continue;
}

int x, y;
cin >> x >> y;

int *S = mp[f]; // 当前的"位置侧"
int *T = mp[f ^ 1]; // 对侧

int u = S[x], v = S[y]; // 原来 x—u、y—v 两条边

// 拆掉 x—u、y—v,重连成 x—v、y—u
// 用 tie + make_tuple 一次性赋值:右边先整体求值,
// 天然避开"先改哪个、后改哪个"的顺序陷阱
tie(S[x], S[y], T[u], T[v]) = make_tuple(v, u, y, x);
}

// 最后按 f 定向,输出对应的那一侧
const int *R = mp[f];
for (int i = 1; i <= n; i++)
cout << R[i] << " \n"[i == n];

return 0;
}

AC代码

https://atcoder.jp/contests/abc470/submissions/78275932

心路历程(WA,TLE,MLE……)