POJ 1166 敌兵布阵 单点更新 区间求和 树型数组

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
const int N=5e4+10;
int tree[N],A[N];//A[]为原数组
int n;//n为要用到的规模
inline int lowbit(int x) { //求取转化为二进制时最低位1+一串0的数
	return x&(-x);
}
inline string readS()//快读字符串 
{
    char ch = getchar();
    string st1 = "";
    while (!(((ch >= 'a') && (ch <= 'z')) || ((ch >='A') && (ch <='Z'))))
        ch = getchar();
    while ((((ch >= 'a') && (ch <= 'z')) || ((ch >='A') && (ch <='Z'))))
        st1 += ch, ch = getchar();
    return st1;
}
inline int read(){//快读  不要在与同一行有string的情况下使用 
	char ch=getchar();
	int s=0,w=1;
	while(ch<'0' || ch>'9'){
		if(ch=='-')	w*=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){//不要写成|| ! 
		s=ch-'0'+(s<<3)+(s<<1);
		ch=getchar();//不要忘记! 
	}
	return s*w;
}
void updata(int idx,int delta) { // 单点更新	对原数组直接修改,对树状数组增加向上升纯	注意这里的delta是变化值而不是修改后的值
	A[idx]+=delta;
	while(idx <= n) {
		tree[idx] += delta;
		idx += (idx & -idx);
	}
}
int sum(int idx) { //求前缀和 累加向下升纯	Sum(1~idx)
	int s = 0;
	while(idx > 0) {
		s += tree[idx];
		idx -= (idx & -idx);
	}
	return s;
}
int sumRange(int i,int j) { //区间求和sum[i,j]	虽然说有些情况下会多运算几次,但是已经很优秀了
	int res = 0;
	i --;
	while(i != j) {
		res = res + tree[j] - tree[i];
		i -= lowbit(i);
		j -= lowbit(j);
	}
	return res;
}
int main() {
	int T=read();
	for(int i=1; i<=T; i++) { //T组数据
		cout<<"Case "<<i<<":"<<endl;
		memset(tree,0,sizeof(tree));
		n=read();
		for(int j=1; j<=n; j++) {
			int v;cin>>v;
			updata(j,v);
		}
		string input;
		while(1) {
			input=readS();
			if(input[0]=='E')	break;
			int x=read(),y=read();
			if(input[0]=='A')	updata(x,y);
			else if(input[0]=='S')	updata(x,-y);
			else cout<<sumRange(x,y)<<endl;
		}
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值