HDU 1166(线段树)

题目链接:点击打开链接


题目大意:给你n个数字,四种命令,end结束,add i j给第i个数字加j,sub i j给第i个数字减j,query i,j查询i到j区间和


题目思路:纯线段树模板题..搞了几个小时终于可以在不看题解的情况下弄出来了主要参考kuangbin大佬模板,再次感谢

build函数建立线段树。输入也是这个时候。不断的递归拆成两半,直到剩下一个数字就输入,同时递归的时候有加和操作,顺便就完成了线段树的初始化

add函数是给包含第i个数字的所有区间都进行操作。t<=mid就说明第i个数字在区间的中间左边,所以继续add(i<<1,t,s)往左走,反之亦然。

sum查询函数,也是一直拆,遇到在区间内就加起来,到最后全加起来正好是所需要的区间


以下是代码:

#include
#include
#include
using namespace std;
#define MAXN 50005
struct node{
    int l,r,sum;
}segTree[MAXN<<2];
void build(int i,int l,int r){
    segTree[i].l=l,segTree[i].r=r;
    if(l==r){
        scanf("%d",&segTree[i].sum);
        return;
    }
    int mid=(l+r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum;
}
void add(int i,int t,int s){
    segTree[i].sum+=s;
    if(segTree[i].l==segTree[i].r){
        return;
    }
    int mid=(segTree[i].l+segTree[i].r)>>1;
    if(t<=mid) add(i<<1,t,s);
    else add(i<<1|1,t,s);
}
int sum(int i,int l,int r){
    if(segTree[i].l==l&&segTree[i].r==r){
        return segTree[i].sum;
    }
    int mid=(segTree[i].l+segTree[i].r)>>1,ans=0;
    if(r<=mid) ans=sum(i<<1,l,r);
    else if(l>mid) ans=sum(i<<1|1,l,r);
    else ans=sum(i<<1,l,mid)+sum(i<<1|1,mid+1,r);
    return ans;
}
int main(){
    int t,tot=1,n,x,y;
    char str[25];
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        build(1,1,n);
        printf("Case %d:\n",tot++);
        while(scanf("%s",str)){
            if(str[0]=='E'){
                break;
            }
            scanf("%d%d",&x,&y);
            if(str[0]=='A'){
                add(1,x,y);
            }
            else if(str[0]=='S'){
                add(1,x,-y);
            }
            else{
                printf("%d\n",sum(1,x,y));
            }
        }
    }
    return 0;
}



你可能感兴趣的:(线段树)