HDU1166 敌兵布阵

本题是一个简单的线段树  用数组模拟形成树状数组进行更改和查询

这倒题我使用了结构体 但是结构体的用处不大

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct sa{
    int x,y,sum;}p[1000520];
    int num;
void updat(int id,int l,int r,int mid,int a){
    if(l==r){
        p[mid].sum+=a;
        p[mid].x=l;
        p[mid].y=r;
        return;
    }
    int i=(l+r)>>1;
    if(id>i)updat(id,i+1,r,2*mid+1,a);//采用递归的方式进行更新
    if(id<=i)updat(id,l,i,2*mid,a);
    p[mid].sum=p[2*mid].sum+p[2*mid+1].sum;
    p[mid].x=l;
    p[mid].y=r;
}//创建和更新用同一个函数  因为意思都差不多
void su(int l,int r,int mid,int ll,int rr){
    if(p[mid].x>=ll&&p[mid].y<=rr){
        num+=p[mid].sum;
        return;
    }
    else{
        int i=(l+r)>>1;
        if(ll<=i)
        su(l,i,2*mid,ll,rr);
        if(rr>i)
            su(i+1,r,2*mid+1,ll,rr);
    }
}//询问函数  询问和的值
int main()
{
    int t,x1,x2;
    scanf("%d",&t);
    int k=1;
    while(t--){
        memset(p,0,sizeof(p));
        int n;
        int a;
        scanf("%d",&n);
        for(int i=1; i<=n; i++){
            scanf("%d",&a);
            updat(i,1,n,1,a);
        }
        printf("Case %d:\n",k++);
        char str[50];
        while(scanf("%s",str)!=EOF){
            if(strcmp(str,"Query")==0){
                scanf("%d%d",&x1,&x2);
                num=0;
                su(1,n,1,x1,x2);
                printf("%d\n",num);
            }
            if(strcmp(str,"Add")==0){
                scanf("%d%d",&x1,&x2);
                updat(x1,1,n,1,x2);
            }
            if(strcmp(str,"Sub")==0)
            {
                scanf("%d%d",&x1,&x2);
                updat(x1,1,n,1,x2*-1);
            }
            if(strcmp(str,"End")==0)break;
        }
    }
    return 0;
}

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