zoukankan      html  css  js  c++  java
  • HDU 1166 敌兵布阵(线段树,单点更新 || 树状数组)

    A - 敌兵布阵
    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
    Submit Status

    Description

    C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视。 
    中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时向Derek汇报某一段连续的工兵营地一共有多少人,例如Derek问:“Tidy,马上汇报第3个营地到第10个营地共有多少人!”Tidy就要马上开始计算这一段的总人数并汇报。但敌兵营地的人数经常变动,而Derek每次询问的段都不一样,所以Tidy不得不每次都一个一个营地的去数,很快就精疲力尽了,Derek对Tidy的计算速度越来越不满:"你个死肥仔,算得这么慢,我炒你鱿鱼!”Tidy想:“你自己来算算看,这可真是一项累人的工作!我恨不得你炒我鱿鱼呢!”无奈之下,Tidy只好打电话向计算机专家Windbreaker求救,Windbreaker说:“死肥仔,叫你平时做多点acm题和看多点算法书,现在尝到苦果了吧!”Tidy说:"我知错了。。。"但Windbreaker已经挂掉电话了。Tidy很苦恼,这么算他真的会崩溃的,聪明的读者,你能写个程序帮他完成这项工作吗?不过如果你的程序效率不够高的话,Tidy还是会受到Derek的责骂的. 
     

    Input

    第一行一个整数T,表示有T组数据。 
    每组数据第一行一个正整数N(N<=50000),表示敌人有N个工兵营地,接下来有N个正整数,第i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=50)。 
    接下来每行有一条命令,命令有4种形式: 
    (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条命令 
     

    Output

    对第i组数据,首先输出“Case i:”和回车, 
    对于每个Query询问,输出一个整数并回车,表示询问的段中的总人数,这个数保持在int以内。 
     

    Sample Input

    1 10 1 2 3 4 5 6 7 8 9 10
    Query 1 3
    Add 3 6
    Query 2 7
    Sub 10 2
    Add 6 3
    Query 3 10
    End
     

    Sample Output

    Case 1:
    6
    33
    59
     
     
    线段树的入门题,从这题可以掌握怎么去创建线段树,更新线段树和查询线段树
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<string>
     4 #include<stdlib.h>
     5 #include<iostream>
     6 #include<algorithm>
     7 using namespace std;
     8 struct node                             //节点结构体
     9 {
    10     int l,r;
    11     int num;
    12 }a[250000];
    13 int ans;
    14 void contree(int l,int r,int now)       //创建线段树
    15 {
    16     a[now].l=l;
    17     a[now].r=r;
    18     if(l==r)                            //如果l==r,说明没有子节点了,那么此时为单个营地,输入人数
    19     {
    20         scanf("%d",&a[now].num);
    21         return ;
    22     }
    23     int mid=(a[now].l+a[now].r)/2;      
    24     contree(l,mid,now<<1);              //递归左子树
    25     contree(mid+1,r,now<<1|1);          //递归右子树
    26     a[now].num=a[now<<1].num+a[now<<1|1].num;
    27 }                                        
    28 void addtree(int l,int r,int now,int vis,int val)   //更新线段树
    29 {
    30     if(l==r&&l==vis)
    31     {
    32         a[now].num+=val;
    33         return ;
    34     }
    35     int mid=(a[now].l+a[now].r)/2;
    36     if(vis>mid)
    37         addtree(mid+1,r,now<<1|1,vis,val);
    38     if(vis<=mid)
    39         addtree(l,mid,now<<1,vis,val);
    40     a[now].num=a[now<<1].num+a[now<<1|1].num;        //每次更改某个值的时候,被查找过的数的值也要更新,这点很重要
    41 }
    42 void sumtree(int l,int r,int now,int L,int R)        //查询线段树
    43 {
    44     if(L<=l&&r<=R)
    45     {
    46         ans+=a[now].num;
    47         return ;
    48     }
    49     int mid=(a[now].l+a[now].r)/2;
    50     if(L>mid)
    51         sumtree(mid+1,r,now<<1|1,L,R);
    52     else if(R<=mid)
    53         sumtree(l,mid,now<<1,L,R);
    54     else
    55     {
    56         sumtree(l,mid,now<<1,L,R);
    57         sumtree(mid+1,r,now<<1|1,L,R);
    58     }
    59 }
    60 int main()
    61 {
    62     int kase,n,cnt=0;
    63     scanf("%d",&kase);
    64     while(kase--)
    65     {
    66         scanf("%d",&n);
    67         contree(1,n,1);
    68         printf("Case %d:
    ",++cnt);
    69         while(1)
    70         {
    71             getchar();
    72             string str;
    73             cin>>str;
    74             int x,y;
    75             ans=0;
    76             if(str=="End")
    77                 break;
    78             scanf("%d %d",&x,&y);
    79             if(str=="Query")
    80             {
    81                 sumtree(1,n,1,x,y);
    82                 printf("%d
    ",ans);
    83             }
    84             else if(str=="Add")
    85                 addtree(1,n,1,x,y);
    86             else
    87                 addtree(1,n,1,x,-y);
    88         }
    89     }
    90     return 0;
    91 }
    View Code

     代码风格稍微小改

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN=50000+10;
     7 struct node
     8 {
     9     int l,r;
    10     int num;
    11     int mid()
    12     {
    13         return (l+r)/2;
    14     }
    15 }a[MAXN*5];
    16 void btree(int l,int r,int step)
    17 {
    18     a[step].l=l;
    19     a[step].r=r;
    20     if(l==r)
    21     {
    22         scanf("%d",&a[step].num);
    23         return ;
    24     }
    25     int mid=a[step].mid();
    26     btree(l,mid,step*2);
    27     btree(mid+1,r,step*2+1);
    28     a[step].num=a[step*2].num+a[step*2+1].num;
    29 }
    30 void ptree(int vis,int val,int step)
    31 {
    32     if(a[step].l==a[step].r&&a[step].l==vis)
    33     {
    34         a[step].num+=val;
    35         return ;
    36     }
    37     int mid=a[step].mid();
    38     if(vis>mid)
    39         ptree(vis,val,step*2+1);
    40     else
    41         ptree(vis,val,step*2);
    42     a[step].num=a[step*2].num+a[step*2+1].num;
    43 }
    44 int fintree(int x,int y,int step)
    45 {
    46     if(x<=a[step].l&&a[step].r<=y)
    47         return a[step].num;
    48     int mid=a[step].mid();
    49     if(x>mid)
    50         return fintree(x,y,step*2+1);
    51     else if(y<=mid)
    52         return fintree(x,y,step*2);
    53     else
    54         return fintree(x,y,step*2)+fintree(x,y,step*2+1);
    55 }
    56 int main()
    57 {
    58     int T,cnt=0;
    59     char str[30];
    60     scanf("%d",&T);
    61     while(T--)
    62     {
    63         int n;
    64         scanf("%d",&n);
    65         btree(1,n,1);
    66         printf("Case %d:
    ",++cnt);
    67         while(scanf("%s",str)!=EOF)
    68         {
    69             if(str[0]=='E')
    70                 break;
    71             int x,y,ans;
    72             scanf("%d %d",&x,&y);
    73             if(str[0]=='A')
    74                 ptree(x,y,1);
    75             if(str[0]=='S')
    76                 ptree(x,-y,1);
    77             if(str[0]=='Q')
    78             {
    79                 ans=fintree(x,y,1);
    80                 printf("%d
    ",ans);
    81             }
    82         }
    83     }
    84     return 0;
    85 }
    View Code

     树状数组的写法

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<stdlib.h>
    #include<algorithm>
    using namespace std;
    const int MAXN=50000+10;
    int a[MAXN],T,n;
    char str[10];
    int lowbit(int x)
    {
        return x&-x;
    }
    int Query(int x)
    {
        int sum=0;
        while(x>0)
        {
            sum+=a[x];
            x-=lowbit(x);
        }
        return sum;
    }
    void Add(int x,int val)
    {
        while(x<=n)
        {
            a[x]+=val;
            x+=lowbit(x);
        }
    }
    int main()
    {
        int cnt=0,val;
        scanf("%d",&T);
        while(T--)
        {
            memset(a,0,sizeof(a));
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&val);
                Add(i,val);
            }
    
            printf("Case %d:
    ",++cnt);
            while(scanf("%s",str))
            {
                int numa,numb;
                if(str[0]=='E') break;
                scanf("%d %d",&numa,&numb);
                if(str[0]=='A')
                    Add(numa,numb);
                else if(str[0]=='S')
                    Add(numa,-numb);
                else
                    printf("%d
    ",Query(numb)-Query(numa-1));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Delphi 2009 新增单元 Character[1]: ToUpper、ToLower
    复制整个文件夹(当然包括嵌套文件夹)
    Delphi 的匿名多线程
    Delphi 2009 泛型容器单元(Generics.Collections)[4]: TDictionary<T>
    Delphi 2009 泛型容器单元(Generics.Collections)[3]: TStack<T>
    Delphi 2009 泛型容器单元(Generics.Collections)[2]: TQueue<T>
    Delphi XE 10.3.3 RSA 签名(IdSSLOpenSSLHeaders)
    Delphi XE 与 Delphi 7 转换
    webacula安装部署流程
    webacula root登陆密码错误解决方案
  • 原文地址:https://www.cnblogs.com/clliff/p/3893559.html
Copyright © 2011-2022 走看看