学习线段树~~~~~~~~~~~~要好好理解
此题是单点更新的线段树,考虑基本的询问,更新。
#include <iostream> #include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <vector> #include <set> #include <queue> #include <stack> #include <climits>//形如INT_MAX一类的 #define MAX 50005 #define INF 0x7FFFFFFF #define REP(i,s,t) for(int i=(s);i<=(t);++i) #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define mp(a,b) make_pair(a,b) # define eps 1e-5 //#pragma comment(linker, "/STACK:36777216") ///传说中的外挂 using namespace std; struct node { int left,right,mid,value,cover; } edge[4*MAX]; void build(int l,int r,int num) //l,r为当前节点的左右端点,num为当前节点在数组中的下标 { edge[num].left = l; edge[num].right = r; edge[num].value = 0; edge[num].mid = (l+r) >> 1; if(l != r) // 如果不是叶子节点 { build(l,edge[num].mid,num * 2); //左子树 build(edge[num].mid + 1,r,num*2+1); //右子树 } } void update(int num,int mid,int v) //单点更新 mid为更新点,v为更新值 { if(edge[num].left == mid && edge[num].right == mid) { edge[num].value += v; return ; } if(edge[num].mid >= mid) update(2*num,mid,v); else update(2*num+1,mid,v); edge[num].value = edge[num*2].value + edge[num*2+1].value; // 注意是‘=’不是‘+=’,更新值 } int query(int l,int r,int num) { if(l <= edge[num].left && r >= edge[num].right) { return edge[num].value; } if(r <= edge[num].mid) return query(l,r,num*2); else if(l >= edge[num].mid + 1) return query(l,r,num *2+1); else { return query(l,edge[num].mid,num*2) + query(edge[num].mid+1,r,num*2+1); } } /* void insert(int l,int r ,int num) //l,r为插入段的左右端点,num为当前结点的下标 { if(l <= edge[num].left && r >= edge[num].right) //插入段完全大于当前段 { edge[num].cover = 1; return ; } if(r <= edge[num].mid) //插入段被当前段的左子树包含 insert(l,r,2 * num); else if(l >= edge[num].mid + 1)//插入段被当前段的右子树包含 insert(l,r,2*num+1); else { insert(l,edge[num].mid, 2* num); insert(edge[num].mid+1,r,2*num+1); } } */ int main() { int t,i,j; int casee = 1; char str[10]; cin >> t; while(t--) { printf("Case %d:\n",casee++); int n,a; cin >> n; build(1,n,1); for(i=1; i<=n; i++) { scanf("%d",&a); update(1,i,a); } while(scanf("%s",str)) { if(str[0] == 'E') break; if(str[0] == 'Q') { scanf("%d%d",&i,&j); printf("%d\n",query(i,j,1)); } if(str[0] == 'A') { scanf("%d%d",&i,&j); update(1,i,j); } if(str[0] == 'S') { scanf("%d%d",&i,&j); update(1,i,-j); } } } return 0; }