首页 > 代码库 > kuangbin专题七、线段树
kuangbin专题七、线段树
题意:线段树,单点更新,区间查询
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 7 const int maxn=5e4+5; 8 int sum[maxn*4]; //sum求和,开四倍空间 9 int num[maxn]; //存原数组下标[1,n] 10 11 //up更新节点信息,这里是求和 12 void up(int rt) 13 { 14 sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 15 } 16 //build建立线段树 17 void build(int rt,int l,int r) 18 { 19 if(l==r)//若到达叶节点 20 { 21 sum[rt]=num[l]; //存储A数组的值 22 return; 23 } 24 int m=(l+r)>>1; 25 build(rt<<1,l,m);//左右递归 26 build(rt<<1|1,m+1,r); 27 up(rt); //更新信息 28 } 29 void update(int p,int add,int rt,int l,int r) 30 { 31 if(l==r)//到达叶节点,修改叶节点的值 32 { 33 sum[rt]+=add; 34 return; 35 } 36 int m=(l+r)>>1; 37 //根据条件判断往左子树调用,还是往右 38 if(p>m) update(p,add,rt<<1|1,m+1,r); 39 else update(p,add,rt<<1,l,m); 40 up(rt); //子节点更新了,本节点也要更新 41 } 42 int query(int L,int R,int rt,int l,int r) 43 { 44 if(L<=l && r<=R) return sum[rt];//区间内直接返回 45 int m=(l+r)>>1; 46 //累加答案 47 int ret=0; 48 if(L<=m) ret+=query(L,R,rt<<1,l,m);//左子区间有重叠,递归 49 if(R>m)ret+=query(L,R,rt<<1|1,m+1,r);//右子区间有重叠,递归 50 return ret; 51 } 52 int main() 53 { 54 int t; 55 scanf("%d",&t); 56 for(int kase=1;kase<=t;kase++) 57 { 58 int n; 59 memset(sum,0,sizeof(sum)); 60 scanf("%d",&n); 61 for(int i=1;i<=n;i++) 62 scanf("%d",&num[i]); 63 build(1,1,n); 64 printf("Case %d:\n",kase); 65 char s[10]; 66 while(scanf("%s",&s)!=EOF && strcmp(s,"End")) 67 { 68 int x,y; 69 scanf("%d%d",&x,&y); 70 if(s[0]==‘Q‘)printf("%d\n",query(x,y,1,1,n)); 71 else if(s[0]==‘A‘)update(x,y,1,1,n); 72 else if(s[0]==‘S‘)update(x,-y,1,1,n); 73 } 74 } 75 return 0; 76 }
kuangbin专题七、线段树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。