hdu1166 敌兵布阵-----(线段树)

来源:互联网 发布:linux内核设计艺术pdf 编辑:程序博客网 时间:2024/06/05 03:17

用到了 线段树 ,好厉害的题

这里要用 scanf 而不是 cin ,不然会超时的。

参考:http://www.cnblogs.com/TenosDoIt/p/3453089.html

#include <iostream>#include <cstdio>using namespace std;int amount[200000];/* l和r表示线段树中该结点的左端点和右端点 root是当前线段树根结点的编号*/void build(int l,int r,int root){    //创建线段树    int mid;    if(l==r)    {        scanf("%d",&amount[root]);//读入每个兵营的初始人数        return;    }    mid=(l+r)/2;    build(l,mid,2*root);     //递归构造左子树    build(mid+1,r,2*root+1); //递归构造右子树    amount[root]=amount[2*root]+amount[2*root+1];}/* i~j是查找范围,*/int query(int i,int j,int left,int right,int root){    int mid,sum=0;    if((i<=left)&&(right<=j))  //该结点的左右端点包含于查找范围之内        return amount[root];    mid=(left+right)/2;    if(i<=mid)//左子树与查找范围有交集        sum+=query(i,j,left,mid,2*root);     //递归查找左子树    if(j>=mid+1)//右子树与查找范围有交集        sum+=query(i,j,mid+1,right,2*root+1);//递归查找右子树    return sum;}void updata(int l,int r,int root,int i,int value){    int mid;    if(l==r)    {        amount[root]+=value;        return;    }    mid=(l+r)/2;    if(i<=mid)        updata(l,mid,2*root,i,value);    else        updata(mid+1,r,2*root+1,i,value);    amount[root]=amount[2*root]+amount[2*root+1];}int main(){    int T;    scanf("%d",&T);    int Case=1;    while(T--)    {        int n,i,j;        char str[10];        scanf("%d",&n);        build(1,n,1);        printf("Case %d:\n",Case++);        while(scanf("%s",str)!=-1&&str[0]!='E')        {            scanf("%d%d",&i,&j);            if(str[0]=='A')            {                updata(1,n,1,i,j);            }            else if(str[0]=='S')            {                updata(1,n,1,i,-j);            }            else                printf("%d\n",query(i,j,1,n,1));        }    }    return 0;}


原创粉丝点击