共42道题,当前是第27

初赛真题

Qjl 是一名神犇,他最近出了一场盛大的 $AK$ 赛。比赛共含有 $n(1 \leq n \leq 100000)$ 题, 由于是 $AK$ 赛,任何人做了任何一道题都能保证 $AC$。但是 Qjl 身为神犇,要摆神犇的架子,具体做法是对于不同的题,赋予不同的满分,这样会让 $AK$ 者的分数变得好看。不过,他的比赛中不断会出现出锅的情况,也就是题目满分应该被调整。他会不断调整一些题目的满分,使之更合理。现在 Qjl 需要你编写程序,帮他满足两种操作,如果你写出了代码,你有可能会获得 $2147483648\%32768$ 分的额外满分! 他首先给你两个正整数 $n,m$ ,表示题目数与操作数;然后他会给你 $n$ 个正整数, 表示这些题目初始的满分。接下来他会不断给你发 $m$ 条操作指令:
`1 x y k` :表示将题号 $i \in [x,y]$  的题目的满分都加上 $k$ ;
`2 x y` :表示询问题号 $i \in [x,y]$ 的所有题目的 $AK$ 分(即总分和)。 

请你编写程序,以享受 $AK$ 的快感。

#include<bits/stdc++.h>

#define int long long
using namespace std;
struct point {
	int lft, rgt, num, lzy;
} a[400401];
int b[100001], n, m, i, x, y, z, t;
void build(int p, int l, int r) {
	a[p].lft = l;
	a[p].rgt = r;
	if (l == r) {
		a[p].num = b[l];
		return;
	}
	build(___(1)___, l, (l + r) / 2);
	build(___(2)___, (l + r) / 2 + 1, r);
	a[p].num = a[p * 2].num + a[p * 2 + 1].num;
}
void down(int p) {
	if (___(3)___) {
		a[p * 2].num += a[p].lzy * 
						(a[p * 2].rgt - a[p * 2].lft + 1);
		a[p * 2 + 1].num += a[p].lzy * 
							(a[p * 2 + 1].rgt - a[p * 2 + 1].lft + 1);
		a[p * 2].lzy += a[p].lzy;
		a[p * 2 + 1].lzy += a[p].lzy;
		___(4)___;
	}
}
void add2(int nd, int st, int ed, int x) {
	if (st <= a[nd].lft && ed >= a[nd].rgt) {
		a[nd].num += ___(5)___;
		a[nd].lzy += x;
		return;
	}
	down(nd);
	if (st <= (a[nd].lft + a[nd].rgt) / 2) add2(nd * 2, st, ed, x);
	if (ed >= (a[nd].lft + a[nd].rgt) / 2 + 1) add2(nd * 2 + 1, st, ed, x);
	a[nd].num = a[nd * 2].num + a[nd * 2 + 1].num;
}
int Find(int nd, int l, int r) {
	if (___(6)___) return ___(7)___;
	down(nd);
	int bb = 0;
	if (l <= (a[nd].lft + a[nd].rgt) / 2) bb += Find(nd * 2, l, r);
	if (r >= (a[nd].lft + a[nd].rgt) / 2 + 1) bb += Find(nd * 2 + 1, l, r);
	return bb;
}
signed main() {
	scanf("%lld%lld", & n, & m);
	for (i = 1; i <= n; i++) {
		scanf("%lld", & b[i]);
	}
	build(1, 1, n);
	for (i = 1; i <= m; i++) {
		scanf("%lld", & t);
		if (t == 1) {
			scanf("%lld%lld%lld", & x, & y, & z);
			add2(1, x, y, z);
		} else {
			scanf("%lld%lld", & x, & y);
			printf("%lld\n", Find(1, x, y));
		}
	}
}

1. A。
2. D。
3. B。
4. C。
5. A。

这段代码是经典的线段树延迟更新标记维护区间加法和区间查询。需要注意的是在标记下推函数中不要递归下推标记,否则复杂度会变成单次操作 $O(nlogn)$ 级别。

Question

1. 填入 (1) 和 (2) 的代码分别是( )。

2. 填入 (3) 处的代码是( )。

3. 填入 (4) 处的代码是( )。

4. 填入 (5) 处的代码是( )。

5. 填入 (6) 和 (7) 处的代码分别是( )。

陈伦制作 版权所无 粤ICP备16127491号-1