http://acm.uestc.edu.cn/#/problem/show/1324
思路:基础分块,这个是一个特别简单的分块,就当做是一个练习了。然后这题也是很简单的单点线段树更新。
//看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespace std; #pragma comment(linker,"/STACK:102400000,102400000") #define LL long long #define ALL(a) a.begin(), a.end() #define pb push_back #define mk make_pair #define fi first #define se second #define haha printf("haha ") const int maxn = 1e5 + 5; ///block表示块的大小,num表示一共分成多少个块 ///belong表示这个数在哪个块里面,l和r表示左右边界 /* 查询操作的话,如果x和y是在同一个块里面,就暴力。 如果不是在一个块里面的话,先暴力[x, r[belong[x]]],然后再暴力块 然后再暴力[l[belong[y]], y] */ int block, num, l[maxn], r[maxn], belong[maxn], n, q; LL Max[maxn], a[maxn]; void build(){ block = sqrt(n); num = n / block; if (n % block) num++; for (int i = 1; i <= num; i++) l[i] = (i - 1) * block + 1, r[i] = i * block; r[num] = n; for (int i = 1; i <= n; i++){ belong[i] = (i - 1) / block + 1; } } void update(int x, int y){ a[x] += y * 1LL; Max[belong[x]] = max(Max[belong[x]], a[x]); } int query(int x, int y){ LL ans = 0; if (belong[x] == belong[y]){ for (int i = x; i <= y; i++) ans = max(ans, a[i]); return ans; } for (int i = x; i <= r[belong[x]]; i++){ ans = max(ans, a[i]); } for (int i = belong[x] + 1; i <= belong[y] - 1; i++) ans = max(ans, Max[i]); for (int i = l[belong[y]]; i <= y; i++) ans = max(ans, a[i]); return ans; } int main(){ cin >> n >> q; build(); for (int i = 1; i <= q; i++){ int op, x, y; scanf("%d%d%d", &op, &x, &y); if (op == 1) update(x, y); else printf("%d ", query(x, y)); } return 0; }