hdu1166 敌兵布-线段树的简单应用-查询更改

来源:互联网 发布:iphone6s没有4g网络 编辑:程序博客网 时间:2024/06/04 19:03

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1166


思路线段树的简单更新查找应用


代码:

#include<cstdio>#include<iostream>using namespace std;#define maxn 50000struct mtree{    int b,e;//b-e为区间    int sum;}tree[maxn*4];void build(int node,int b,int e){    tree[node].b=b;    tree[node].e=e;    tree[node].sum=0;    if(b==e) return;    int mid=(b+e)/2;    //左儿子    if(b<=mid)    {        build(node*2,b,mid);    }    //右儿子    if(mid<e)        build(node*2+1,mid+1,e);}void update(int node,int n,int x){    if(tree[node].b==tree[node].e && tree[node].e ==n)    {        tree[node].sum+=x;        return;    }    int mid=(tree[node].b+tree[node].e)/2;    if(n<=mid) update(node*2,n,x);//往左查找    else update(node*2+1,n,x);    tree[node].sum=tree[node*2].sum+tree[node*2+1].sum;}int query(int node,int b,int e){    int ans1=0,ans2=0;    if(tree[node].b>=b&&tree[node].e<=e)//查询空间包括了树的区间才能取值    {        return tree[node].sum;    }    int mid=(tree[node].b+tree[node].e)/2;    if(b<=mid)        ans1=query(node*2,b,e);    if(mid<e)        ans2=query(node*2+1,b,e);    return ans1+ans2;}int main(){    int t,i,j;    scanf("%d",&t);    for(j=1;j<=t;++j)    {        int n,a;        char s[10];        int x,y;        scanf("%d",&n);        build(1,1,n);//建树        for(i=1;i<=n;++i)        {            scanf("%d",&a);            update(1,i,a);        }        printf("Case %d:\n",j);        while(scanf("%s",s))        {            if(s[0]=='E') break;            if(s[0]=='A')            {                scanf("%d%d",&x,&y);                update(1,x,y);            }            if(s[0]=='S')            {                scanf("%d%d",&x,&y);                update(1,x,-y);            }            if(s[0]=='Q')            {                scanf("%d%d",&x,&y);                printf("%d\n",query(1,x,y));            }        }    }    return 0;}

2 0