线段树(补)
这个东西是真的难懂,具体的可以去看别的详细的博客学习。这里只上个例题。
例:HDU - 1166 (http://acm.hdu.edu.cn/showproblem.php?pid=1166)
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#pragma warning(disable:4996)
using namespace std;
const int MAXN = 1e5 + 10;
const int inf = 0x3f3f3f3f;
const int N = 50010;
int a[N];
struct segmenttree {
int l;
int r;
int sum;
}h[N<<2];
void pushup(int i) {
h[i].sum = h[i << 1].sum + h[i << 1 | 1].sum;
}
void build(int l,int r,int i) {
h[i].l = l;
h[i].r = r;
if (l == r) {
h[i].sum = a[l];
return;
}
int mid = l + r >> 1;
build(l, mid, i << 1);
build(mid+1, r, i << 1 | 1);
pushup(i);
}
void modify(int p, int w, int i) {
if (h[i].l == p && h[i].r == p) {
h[i].sum += w;
return;
}
int mid = h[i].l + h[i].r >> 1;
if (p <= mid)modify(p, w, i << 1);
else modify(p, w, i << 1 | 1);
pushup(i);
}
int query(int l, int r, int i) {
if (l <= h[i].l && r >= h[i].r) {
return h[i].sum;
}
int mid = h[i].l + h[i].r >> 1;
int res=0;
if (l <= mid) res += query(l, r, i << 1);
if (r > mid) res += query(l, r, i << 1 | 1);
return res;
}
int main() {
int t,n,k=1;
char s[10];
scanf("%d", & t);
while (t--) {
printf("Case %d:\n", k);
k++;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
build(1, n, 1);
int x, y;
while (~scanf("%s",s)) {
if (!strcmp(s, "End"))break;
scanf("%d %d", &x, &y);
if (!strcmp(s, "Add")) {
modify(x, y, 1);
}
else if (!strcmp(s, "Sub")) {
modify(x, -y, 1);
}
else if (!strcmp(s, "Query")) {
printf("%d\n", query(x, y, 1));
}
}
}
return 0;
}