敌兵布阵(线段树) HDU - 1166
一个人养lyd,每盆lyd都有一个价值,lyd是排成一行。有三个操作:有时某盆lyd的价值会上升,有时某盆lyd的价值会下降。有时他想知道某段连续的lyd的价值之和是多少,你能快速地告诉她结果吗?
第一行一个整数T,表示有T组测试数据。 每组测试数据的第一行为一个正整数N (N<=50000),表示有N盆lyd。 接下来有N个正整数,第i个正整数a表示第i盆lyd的初始价值。
接下来每行有一条命令,命令有4种形式: (1)Add i j, i和j为正整数,表示第i盆lyd价值增加j (j<=30) (2)Sub i j, i和j为正整数,表示第i盆lyd价值减少j (j<=30) (3)Query i j, i和j为正整数,i<=j,表示询问第i盆lyd到第j盆lyd的价值之和 (4)End,表示结束,这条命令在每组数据最后出现 每组数据的命令不超过40000条
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cstring> #include<stdio.h> #include<algorithm> #include<map> #include<queue> #include<set> #include <sstream> #include<vector> #include<cmath> #include<stack> #include<time.h> #include<ctime> using namespace std; #define inf 1<<30 #define eps 1e-7 #define LD long double #define LL long long #define maxn 100000005 struct node { int L, R, sum; }tree[maxn]; int num[maxn] = {}; void update(int step) { tree[step].sum = tree[step << 1].sum + tree[step << 1 | 1].sum; } void buildTree(int step,int L,int R)//先把树建了 { tree[step].L = L; tree[step].R = R; if (L == R) { tree[step].sum = num[L]; return; } int mid = (L + R) >> 1; buildTree(step << 1, L, mid);//建左子树 buildTree(step << 1 | 1, mid + 1, R);//建右子树 update(step); } void change(int step, int L, int R, int val)//对树进行修改 { if (L <= tree[step].L && tree[step].R <= R)//当要修改的范围在当前点的范围之内时 { tree[step].sum += val;//修改 return; } int mid = (tree[step].L + tree[step].R) >> 1; if (R <= mid)//要修改的点在左子树时 change(step * 2, L, R, val); else//要修改的点在右子树时 change(step * 2 + 1, L, R, val); update(step);//对所有包含修改点的树进行修改 } int query(int step, int L, int R)//求部分范围之和 { if (L <= tree[step].L && tree[step].R <= R)return tree[step].sum;//在当前点范围内 if (L > tree[step].R || R < tree[step].L)return 0;//在当前点范围外 return query(step * 2, L, R) + query(step * 2 + 1, L, R);//一部分在当前点内,一部分在当前点外 } int main() { int T, Case = 1; string s; scanf("%d", &T); while (T--) { int N, x, y, ans = 0; scanf("%d", &N); for (int i = 1; i <= N; i++) { scanf("%d", &num[i]); } buildTree(1, 1, N); printf("Case %d:\n", Case++);//格式 while (cin >> s) { if (s == "End") { break; } else if (s == "Add") { scanf("%d%d", &x, &y); change(1, x, x, y); } else if (s == "Sub") { scanf("%d%d", &x, &y); change(1, x, x, -1 * y); } else if (s == "Query") { scanf("%d%d", &x, &y); ans=query(1,x, y); printf("%d\n", ans); } } } }