HDU 1166 敌兵布阵【线段树】

来源:互联网 发布:剑三笔记本优化版 编辑:程序博客网 时间:2024/05/16 17:31

题目链接

题目意思

给定一个序列,有三种操作,最后输出给定范围的值之和

题目意思

数据大,普通方法肯定超时,用线段树来计算区间的加法。

代码部分

#include <iostream>#include <stdio.h>#include <string.h>#define lchild left,mid,root<<1#define rchild mid+1,right,root<<1|1using namespace std;const int maxn=50005;int sum[maxn<<2];int n;///更新线段树节点void push_up(int root){    sum[root]=sum[root<<1]+sum[root<<1|1];}///构造线段树void build(int left,int right,int root){    if(left==right)    {        int num;        scanf("%d",&num);        sum[root]=num;        return;    }    int mid=(left+right)>>1;    build(lchild);    build(rchild);    push_up(root);}///更改操作void updata(int aim,int num,int left,int right,int root){    if(left==right)    {        sum[root]+=num;        return;    }    int mid=(left+right)>>1;    if(mid>=aim)        updata(aim,num,lchild);    else        updata(aim,num,rchild);    push_up(root);}///查询操作int query(int L,int R,int left,int right,int root){    if(L<=left&&right<=R)    {        return sum[root];    }    int ans=0;    int mid=(left+right)>>1;    if(R<=mid)        ans+=query(L,R,lchild);    else if(L>mid)        ans+=query(L,R,rchild);    else    {        ans+=query(L,R,lchild);        ans+=query(L,R,rchild);    }    return ans;}int main(){    int t,temp=1;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        build(1,n,1);        string s;        cout<<"Case "<<temp++<<":"<<endl;        while(cin>>s)        {            int n1,n2;            if(s[0]=='E')                break;            if(s[0]=='Q')            {                scanf("%d%d",&n1,&n2);                int ans=query(n1,n2,1,n,1);                cout<<ans<<endl;            }            if(s[0]=='A')            {                scanf("%d%d",&n1,&n2);                updata(n1,n2,1,n,1);            }            if(s[0]=='S')            {                 scanf("%d%d",&n1,&n2);                updata(n1,-n2,1,n,1);            }        }    }    return 0;}
原创粉丝点击