HDU 1166 ZKW线段树 单点修改+区间求和

/**
HDU 1166  ZKW线段树
https://vjudge.net/problem/HDU-1166
区间和+单点更新
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn = 1e5+7;
int M,n,a[maxn<<2];

int d[maxn<<2];

//下标为1,询问区间和[l,r]:贡献:l的右儿子,r的左儿子;
int query(int l,int r){
	int ans=0;
	l+=M-1,r+=M+1;
	for(;l^r^1;l>>=1,r>>=1){
		if(l&1^1) ans+=d[l^1];//l的右儿子
		if(r&1)  ans+=d[r^1];//r的左儿子
	}
	return ans;
}

//单点修改d[x] += val ;
void add(int x,int val){
    x+=M;
	d[x]+=val;x>>=1;
	for(;x;x>>=1) d[x]=d[x<<1]+d[x<<1|1];//一层一层的往上面进行更新;
}
char op[20];

int main (){
	int t;scanf("%d",&t);
	for(int cas=1;cas<=t;cas++){
		scanf("%d",&n);for(M=1;M<n;M<<=1);
		memset(d,0,sizeof(d));
		for(int i=M+1;i<=M+n;i++) scanf("%d",&d[i]);
		for(int i=M-1;i>=1;i--) d[i]=d[i<<1]+d[i<<1|1];
		printf("Case %d:\n",cas);
		while(~scanf("%s",op)&&strcmp(op,"End")!=0) {
			int l,r;scanf("%d %d",&l,&r);
			if(op[0]=='Q') printf("%d\n",query(l,r));
			else if(op[0]=='A') add(l,r);
			else add(l,-r);
		}
	}
	return 0;
}

/**
9
7
1 2 1 2 2 3 4
Query 2 7
*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值