HDOJ1166(线段树-单点更新)

    /* 
    HDOJ1166 
    作者:陈佳润 
    时间:2013-03-29 
    */  
    #include<iostream>  
    #include<string.h>  
    using namespace std;  
    #define MaxSize 50001  
    int Tree[MaxSize*4];  
       
    void Create(int p,int l,int r){//可存在[a,a]的节点  
        if(l==r){//当达到叶子节点时  
            scanf("%d",&Tree[p]);  
            return;  
        }  
        int mid=(l+r)>>1;//计算中间值  
        Create(p<<1,l,mid);//向左递归  
        Create(p<<1|1,mid+1,r);//向右递归  
        Tree[p]=Tree[p<<1]+Tree[p<<1|1];//计算节点值  
    }  
    void Add(int i,int add,int p,int l,int r){//增加叶子节点数值  
        if(l==r){//当达到叶子节点时,加上修改值  
            Tree[p]+=add;  
            return ;  
        }  
        int mid=(l+r)>>1;//计算中间值  
        if(i<=mid)//向左递归  
            Add(i,add,p<<1,l,mid);  
        else//向右递归  
            Add(i,add,p<<1|1,mid+1,r);  
        Tree[p]=Tree[p<<1]+Tree[p<<1|1];//计算节点值  
    }  
    int Query(int p,int l,int r,int L,int R){  
        if(R>=r&&L<=l)//当查询的区间比树的区间大时  
            return Tree[p];  
        int sum=0;//当前节点的值  
        int mid=(l+r)>>1;//计算中间值  
        if(L<=mid)//向左递归  
            sum+=Query(p<<1,l,mid,L,R);  
        if(R>mid)//向右递归  
            sum+=Query(p<<1|1,mid+1,r,L,R);  
        return sum;  
    }  
    int main(){  
        int Time,n,i,L,R;  
        char command[10];  
    //  freopen("1.txt","r",stdin);  
        cin>>Time;  
        for(i=1;i<=Time;i++){  
            memset(Tree,0,sizeof(Tree));  
            cin>>n;  
            Create(1,1,n);  
            cout<<"Case "<<i<<":"<<endl;  
            while(true){  
                scanf("%s",command);  
                //printf("%sn",command);  
                if(command[0]=='E')  
                    break;//end  
                if(command[0]=='Q'){  
                    scanf("%d%d",&L,&R);  
                    printf("%dn",Query(1,1,n,L,R));  
                }//query  
                if(command[0]=='A'){  
                    scanf("%d%d",&L,&R);  
                    Add(L,R,1,1,n);  
                }//add  
                if(command[0]=='S'){  
                    scanf("%d%d",&L,&R);  
                    Add(L,-R,1,1,n);  
                }//sub  
            }//while(true)  
        }//Time  
        return 0;  
    }//main  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值