您的位置:首页 > 其它

HDU 1166 敌兵布阵 线段树求解

2015-04-27 14:56 351 查看
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66989#problem/A

题意:动态修改某个点的值,然后动态询问区间和。

标准的线段树点修改问题,以前做过,第一次看着别人的代码用线段树水过了,后来还用树状数组做过(现在不记得树状数组了。。。。),现在再次用线段树写,当然这次是独立写的。题意本身不难,但是有一个值的注意,本题输入与输出量比较大,得用scanf与printf,否则果断TLE。

代码:

#include<iostream>
#include<cstdio>
#define maxn 50010

using namespace std;
struct node{
int l,r,w;
}T[maxn*3];

int N,A[maxn];//A数组要不要都行,初始时,每输入一个值调用一次add
char s[10];

int build(int L,int R,int o){
T[o].l=L;T[o].r=R;
if(L==R) return T[o].w=A[L];
return T[o].w=build(L,(L+R)/2,o*2)+build((L+R)/2+1,R,o*2+1);
}

void add(int L,int R,int val,int o){
if(T[o].l>=L && T[o].r<=R){
T[o].w+=val;return;
}
if(T[o].l==T[o].r) return;
T[o].w+=val;
int tl=o*2,tr;tr=tl+1;
if(L>=T.l) add(L,R,val,tr);
else if(R<=T[tl].r) add(L,R,val,tl);
else{
add(L,T[tl].r,val,tl);
add(T.l,R,val,tr);
}
}

int query(int L,int R,int o){
if(T[o].l>=L && T[o].r<=R) return T[o].w;
if(T[o].l==T[o].r) return 0;
int tl=o*2,tr;tr=tl+1;
if(L>=T.l) return query(L,R,tr);
if(R<=T[tl].r) return query(L,R,tl);
return query(L,T[tl].r,tl)+query(T.l,R,tr);
}

int main(){
//freopen("D:\\in.txt","r",stdin);
int T;cin>>T;
for(int kase=1;kase<=T;kase++){
cin>>N;
for(int i=0;i<N;i++)
scanf("%d",A+i+1);
build(0,N,1);
printf("Case %d:\n",kase);
while(scanf("%s",s) && s[0]!='E'){
int a,b;
scanf("%d %d",&a,&b);
if(s[0]=='Q') printf("%d\n",query(a,b,1));
else if(s[0]=='A') add(a,a,b,1);
else add(a,a,0-b,1);//减法发也可以是加法
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: