0%

题目大意

思路讲解

AC代码

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

题目大意

给定多组数据。每组有 n 匹马按编号 1..n 排列,m 个饲料槽编号 1..m

初始时第 i 匹马分配到槽 a_i,其中 a_i=0 表示未分配。每个槽的投喂总量 b_i 初始都是 0

需要按顺序执行 q 次操作,每次输入 opt, l, r, x

  • opt=1:把区间 [l,r] 内所有马的分配槽改为 x

  • opt=2:对区间 [l,r] 内每匹马,如果它当前已分配槽(a_i≠0),就给它所在槽增加 x 的投喂量(累加到对应 b_{a_i})。

所有操作结束后,输出 m 个数,表示每个槽最终投喂总量 b_1..b_m

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

Sample Output
23 3 3 8

样例过程对应含义:

  • 初始分配:[1,0,3,2,4,1],所有 b_i=0

  • 操作 2 1 4 3:马 1..4 中已分配的有 1,3,4 号马,分别给槽 1,3,2 各加 3

  • 操作 1 2 5 1:马 2..5 全部分配到槽 1

  • 操作 2 1 6 2:马 1..6 都已分配,按当前分配给对应槽加 2

  • 操作 1 3 4 4:马 3..4 改分配到槽 4

  • 操作 2 2 5 4:马 2..5 都已分配,按当前分配给对应槽加 4

最终各槽投喂总量为:23 3 3 8

思路讲解

2025 河南省赛——Problem C. Toxel 与宝可梦图鉴(珂朵莉树+值域线段树维护全局信息)(因为这道题目,可以设计珂朵莉树无这个查询操作,只有 assign 操作,因此严格 O(nlogn))(区间等差数列赋值,全局查询最小众数)

PDF

PDF

这个下面的这个避免树状数组清空的技巧还是非常有用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
	void assign(ll la, ll ra, ll val) {
split(la);
split(ra + 1);
auto it = mpODT.lower_bound(la);
#ifdef LOCAL
assert(it->first==la);
#endif
for (; it != mpODT.end();) {
if (it->first > ra) {
break;
}
ll originV = it->second.val;
ll l = it->first, r = it->second.r;
// 这里是做一些事情,比如说累加答案
ll add = tr->query(l, r);
anss[originV] += add;
anss[val] -= add;
it = mpODT.erase(it);
}
mpODT[la] = {ra, val};
}

image

AC代码

AC

https://acm.hdu.edu.cn/contest/view-code?cid=1201&rid=9803

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

题目大意

题意总结

给定长度为 N 的字符串 S,字符只可能是 01?

把所有 ? 分别替换成 01 后,会得到一个二进制串。

定义“好串”为:所有 1 必须恰好出现在一个连续子串中(可以没有 1,也可以全是 1)。

对一个确定的二进制串,定义 f(S) 为把它变成“好串”的最少操作次数。

一次操作是:选 1 ≤ i < j ≤ N,交换 S[i]S[j]

每个测试用例要求输出两件事:

  • 在所有可能替换方案里,f(S) 的最小可能值

  • 在所有可能替换方案里,f(S) 的最大可能值


输入格式

  • 第一行:整数 T,表示测试用例数。

  • 每个测试用例两行:

    • 第一行:整数 N
    • 第二行:长度为 N 的字符串 S

输出格式

每个测试用例输出一行两个整数:min_f max_f,分别表示最小和最大可能的 f(S)


数据范围

  • 1 ≤ T ≤ 100

  • 2 ≤ N ≤ 2000

  • S[i] ∈ {0,1,?}

  • 所有测试用例的 N 之和不超过 2000


样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Input
6
3
1?1
5
1?0?1
7
1?0101?
9
?????????
8
11010101
6
??011?

Output
0 1
1 1
1 2
0 3
2 2
0 1

样例说明(按测试点)

  • 第 1 组:1?1

    • 最小值:取 111,已经是好串,f=0
    • 最大值:取 101,最少交换 1 次变好串,f=1
    • 所以输出 0 1
  • 第 2 组:1?0?1

    • 无论怎么填,f 的最小和最大都为 1
    • 输出 1 1
  • 第 3 组:1?0101?

    • 可构造到 f=1(如 1101010
    • 也可构造到 f=2(如 1101011
    • 输出 1 2
  • 第 4 组:?????????

    • 最小可到 0(如全 0 或全 1
    • 最大可到 3(如 111000111
    • 输出 0 3
  • 第 5 组:11010101

    • 没有 ?,串固定,f 唯一为 2
    • 输出 2 2
  • 第 6 组:??011?

    • 最小可到 0
    • 最大可到 1
    • 输出 0 1

思路讲解

PDF

所谓的均匀分布,其实就是指二分,因为我们想要尽可能均匀分布,选择的指标是最不均匀的最均匀,这个其实就是一个典型的二分。

AC代码

AC
https://www.codechef.com/viewsolution/1265307182

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

题目大意

  • 给定长度为 NN 的数组 AA

  • 好数组(good) 的定义:数组中存在至少一个数值 xx,它在该数组中恰好出现一次

    • 例如 [1,2,1][1,1,2] 是好数组(2 只出现一次)。
    • [1,2,1,2] 不是好数组(每个值都出现两次)。
  • 漂亮数组(beautiful) 的定义:这个数组的每一个子数组(连续子段)都是好数组。

    • 例如 [1,2,1] 是漂亮数组;[1,1,2][1,2,1,2] 不是。
  • 你可以进行若干次修改操作:每次选择位置 ii,把 AiA_i 改成任意整数 xx

  • 目标:对每个测试用例,求把原数组变成漂亮数组所需的最少修改次数

  • 输入格式:

    • 第一行是测试组数 TT
    • 每组先给 NN,再给 NN 个整数 A1,,ANA_1,\dots,A_N
  • 输出格式:

    • 每组输出一个整数,表示最少修改次数。
  • 数据范围:

    • 1T1031 \le T \le 10^3
    • 2N5002 \le N \le 500
    • 1AiN1 \le A_i \le N
    • 所有测试用例的 N2N^2 之和不超过 5002500^2

样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
输入
4
3
1 3 1
3
1 1 2
4
1 2 1 2
6
1 1 1 2 1 2

输出
0
1
1
2
  • 样例第 1 组:[1,3,1] 本身已经是漂亮数组,所以答案是 0

  • 样例第 2 组:[1,1,2] 不是漂亮数组,改一次即可(如把第 2 个数改成 3,得到 [1,3,2]),答案是 1

  • 样例第 3 组:[1,2,1,2] 不是漂亮数组,最少改 1 次。

  • 样例第 4 组:[1,1,1,2,1,2] 最少改 2 次。

思路讲解

PDF

AC代码

AC
https://www.codechef.com/viewsolution/1263070965

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

题目大意

题目描述
给定两个长度为 nn 的整数数组 aabb
qq 次询问,每次询问给定一个区间 [l,r][l, r],提取出子数组 a=a[lr]a' = a[l \dots r]b=b[lr]b' = b[l \dots r],设该子数组长度为 m=rl+1m = r - l + 1
对于每次询问中的子数组,可以执行以下操作任意次:

  1. 选取一个下标 ii1im1 \le i \le m)。

  2. 计算子数组后缀的最大公约数 gi=gcd(ai,ai+1,,am)g_i = \gcd(a'i, a'{i+1}, \dots, a'_m)

  3. bb' 中下标从 iimm 的所有元素减去 gig_i(即对于所有 ijmi \le j \le m,令 bjbjgib'_j \leftarrow b'_j - g_i)。

每次操作的代价为 1。要求计算出使 bb' 中所有元素变为非正数(0\le 0)所需的最小总操作代价。

数据范围

  • 测试组数 TT1T1051 \le T \le 10^5

  • 数组长度与询问次数 n,qn, q1n,q21051 \le n, q \le 2 \cdot 10^5

  • 数组元素范围:1ai1091 \le a_i \le 10^90bi1090 \le b_i \le 10^9

  • 保证 n106\sum n \le 10^6q106\sum q \le 10^6

样例数据

输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
10 10
6 12 18 40 50 60 105 120 135 150
10 20 30 40 50 60 70 80 90 100
5 8
1 3
7 10
6 6
4 7
1 6
2 10
2 4
4 4
5 6

输出

1
2
3
4
5
6
7
8
9
10
12
5
7
1
12
18
38
16
1
6

样例解释
以第 2 次询问 1 3 为例:
提取出的子数组为 a=[6,12,18]a' = [6, 12, 18]b=[10,20,30]b' = [10, 20, 30]
一种可能的最优操作序列如下(共需 5 次操作,代价为 5):

  • 选取 i=1i = 1 操作 2 次:g1=gcd(6,12,18)=6g_1 = \gcd(6, 12, 18) = 6,每次操作使 b1,b2,b3b'_1, b'_2, b'_3 减去 6。操作后 bb' 变为 [2,8,18][-2, 8, 18]

  • 选取 i=2i = 2 操作 2 次:g2=gcd(12,18)=6g_2 = \gcd(12, 18) = 6,每次操作使 b2,b3b'_2, b'_3 减去 6。操作后 bb' 变为 [2,4,6][-2, -4, 6]

  • 选取 i=3i = 3 操作 1 次:g3=gcd(18)=18g_3 = \gcd(18) = 18,每次操作使 b3b'_3 减去 18。操作后 bb' 变为 [2,4,12][-2, -4, -12]
    此时 bb' 中所有元素均不大于 0,所需最小总代价为 2+2+1=52 + 2 + 1 = 5,与输出一致。

思路讲解

PDF

想出一个 O(nq)O(nq) 的做法是不难的,难的就是怎么样在 O(n+q)O(n+q) 或者类似的时间复杂度内解决这个问题。

这个下面就是一个这样的做法:

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
struct Solve {
ll N, Q;
vector<ll> A_glo;
vector<ll> B_glo;
vector<ll> gcd_ls;

ll reply_to_query(ll l, ll r) {
gcd_ls[r] = A_glo[r];
for (int i = r - 1; i >= l; --i) {
gcd_ls[i] = __gcd(gcd_ls[i + 1], A_glo[i]);
}
ll acc = 0;
ll ans = 0;
for (int i = l; i <= r; ++i) {
if (acc >= B_glo[i]) {
continue;
}
ll rem = B_glo[i] - acc;
ll add = (rem + gcd_ls[i] - 1) / gcd_ls[i];
acc += add * gcd_ls[i];
ans += add;
}
return ans;
}

Solve() {
cin >> N >> Q;
A_glo.resize(N + 2);
B_glo.resize(N + 2);
gcd_ls.resize(N + 2);
for (int i = 1; i <= N; ++i) {
cin >> A_glo[i];
}
for (int i = 1; i <= N; ++i) {
cin >> B_glo[i];
}
for (int _ = 1; _ <= Q; _++) {
ll l, r;
cin >> l >> r;
cout << reply_to_query(l, r) << "\n";
}
}
};

image

image

AC代码

AC
https://acm.hdu.edu.cn/contest/view-code?cid=1200&rid=15202

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