HDU 1166 敌兵布阵 (线段树点更新模板题)

来源:互联网 发布:淘宝众筹赚钱吗 编辑:程序博客网 时间:2024/06/09 11:39

题目链接

HDU1166

题目大意

有N个(N<=50000)工兵营地,有N个工兵营地开始时有ai个人(1<=ai<=50)。有以下四种命令:
(1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)
(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);
(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;
(4)End 表示结束,这条命令在每组数据最后出现;
每组数据最多有40000条命令

分析

写线段树的第一道题,点更新模板题。
注意较多数据若都用输入输出流,会TLE。解决方法:关闭和stdio同步,即调用ios::sync_with_stdio(false);

代码

#include <iostream>#include <cstring>#include <string>using namespace std;const int MAXN=50010;int a[MAXN],ans[4*MAXN];void PushUp(int rt){    ans[rt]=ans[rt<<1]+ans[rt<<1|1];}void Build(int l,int r,int rt){    if (l==r)    {        ans[rt]=a[l];        return;    }    int mid=(l+r)>>1;    Build(l,mid,rt<<1);    Build(mid+1,r,rt<<1|1);    PushUp(rt);}void Add(int L,int C,int l,int r,int rt){    if (l==r)    {        ans[rt]+=C;        return;    }    int mid=(l+r)>>1;    if (L<=mid)        Add(L,C,l,mid,rt<<1);    else        Add(L,C,mid+1,r,rt<<1|1);    PushUp(rt);}int Query(int L,int R,int l,int r,int rt){    if (L<=l&&r<=R)        return ans[rt];    int mid=(l+r)>>1;    int ANS=0;    if (L<=mid)        ANS+=Query(L,R,l,mid,rt<<1);    if (R>mid)        ANS+=Query(L,R,mid+1,r,rt<<1|1);    return ANS;}int main(){    ios::sync_with_stdio(false); ///加速流输入输出,否则会超时    int t,n,i,x,y,cnt=0;    string op;    cin>>t;    while (t--)    {        cin>>n;        for (i=1;i<=n;i++)            cin>>a[i];        memset(ans,0,sizeof(ans));        Build(1,n,1);        cout<<"Case "<<++cnt<<":"<<endl;        while (1)        {            cin>>op;            if (op=="End") break;            cin>>x>>y;            if (op=="Add") Add(x,y,1,n,1);            if (op=="Sub") Add(x,-y,1,n,1);            if (op=="Query") cout<<Query(x,y,1,n,1)<<endl;        }    }    return 0;}
0 0