HDU 1166 敌兵布阵

来源:互联网 发布:存照片的软件 编辑:程序博客网 时间:2024/05/16 05:03

敌兵布阵

题目链接:点击打开链接


题目和本博客里之前的题目没什么区别,都是典型的树状数组增删改查。


代码如下:

#include<stdio.h>#include<string.h>#define MAXN 50005int tree[MAXN];int data[MAXN];void add(int x,int num){for(int i=x;i<MAXN;i+=i&(-i))tree[i]+=num;}int read(int x){int sum=0;for(int i=x;i>0;i-=i&(-i))sum+=tree[i];return sum;}void A(){int x,num;scanf("%d%d",&x,&num);x++;add(x,num);}void S(){int x,num;scanf("%d%d",&x,&num);x++;add(x,-num);}void Q(){int x,y;scanf("%d%d",&x,&y);x++;y++;int sum=read(y)-read(x-1);printf("%d\n",sum);}int main(){int t,n;int index=1;char str[10];scanf("%d",&t);while(t--){memset(tree,0,sizeof(tree));scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&data[i]);add(i+2,data[i]);}printf("Case %d:\n",index++);while(scanf("%s",&str)){if(str[0]=='A')A();else if(str[0]=='S')S();else if(str[0]=='Q')Q();else if(str[0]=='E')break;}}return 0;}

2017/9/27 加入线段树模板代码:

#include<iostream>#include<cstdio>using namespace std;//(0)定义#define maxn 100007 //元素的总个数#define ls,l,m,rt<<1#define rs m+1,r,rt<<1|1void PushDown(int rt,int ln,int rn);//声明void Update(int L,int C,int l,int r,int rt);int Sum[maxn<<2],Add[maxn<<2];  //Sum构成线段树,Add为懒惰数组int n,A[maxn];  //原数组下标[1,n];//(1)建树void PushUp(int rt) {Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];}void Build(int l,int r,int rt)//l,r表示当前结点区间,rt当前节点编号{    if(l==r){        Sum[rt]=A[l];        return ;    }    int m=(l+r)>>1;    Build(l,m,rt<<1);    Build(m+1,r,rt<<1|1);    PushUp(rt);}//(2)点修改void Update(int L,int C,int l,int r,int rt)//l,r表示当前节点区间,rt表示当前节点编号{    if(l==r){        Sum[rt]+=C;        return ;    }    int m=(l+r)>>1;    if(L<=m)    Update(L,C,l,m,rt<<1);    else        Update(L,C,m+1,r,rt<<1|1);    PushUp(rt);}void Update(int L,int R,int C,int l,int r,int rt){    if(L<=l && r<=R){        Sum[rt]+=C*(r-l+1);        Add[rt]+=C;        return ;    }    int m=(l+r)>>1;    PushDown(rt,m-l+1,r-m);    if(L<=m) Update(L,R,C,l,m,rt<<1);    if(R>m) Update(L,R,C,m+1,r,rt<<1|1);    PushUp(rt);}void PushDown(int rt,int ln,int rn){//ln,rn为左子树,右子树的数字数量。    if(Add[rt])    {//下推标记        Add[rt<<1]+=Add[rt];        Add[rt<<1|1]=Add[rt];        Sum[rt<<1]+=Add[rt]*ln;        Sum[rt<<1|1]+=Add[rt]*rn;        Add[rt]=0;  //清除标记    }}int Query(int L,int R,int l,int r,int rt){//L,R表示操作区间,l,r表示当前节点区间,rt表示当前节点编号    if(L <= l && r <= R){        //在区间内,直接返回        return Sum[rt];    }    int m=(l+r)>>1;    //下推标记,否则Sum可能不正确    PushDown(rt,m-l+1,r-m);    //累计答案    int ANS=0;    if(L <= m) ANS+=Query(L,R,l,m,rt<<1);    if(R >  m) ANS+=Query(L,R,m+1,r,rt<<1|1);    return ANS;}int main(){    int L,R,C,n,t;    char str[15];    int l,r,inde;    inde=0;    scanf("%d",&t);    while(t--)    {        printf("Case %d:\n",++inde);        scanf("%d",&n);        for(int i=1;i<=n;i++)            scanf("%d",&A[i]);        Build(1,n,1);//建树        while(1)        {            scanf("%s",&str);            if(str[0]=='E')                break;            else{                scanf("%d%d",&l,&r);                if(str[0]=='A')                    Update(l,r,1,n,1);//点修改                else if(str[0]=='S')                    Update(l,-r,1,n,1);//点修改                else{                    int ANS=Query(l,r,1,n,1);//区间查询                    printf("%d\n",ANS);                }            }        }    }//      Build(1,n,1);//建树//    Update(L,C,1,n,1);//点修改//    Update(L,R,C,1,n,1);//区间修改//    int ANS=Query(L,R,1,n,1);//区间查询    return 0;}


0 0
原创粉丝点击