zoukankan      html  css  js  c++  java
  • hdu 1166 敌军布阵

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

     

    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询问,输出一个整数并回车,表示询问的段中的总人数,这个数最多不超过1000000。
     

    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
     

    思路:用简单数组解此不断变化的数组会超时,so,我们需要跟快的算法!

    数状数组解题代码:

    View Code
     1 // File Name: /media/文档/源程序/实验室/6A.cpp
     2 // Author: sheng
     3 // Created Time: 2013年03月19日 星期二 21时02分05秒
     4 
     5 #include <iostream>
     6 #include <string.h>
     7 #include <cstdio>
     8 using namespace std;
     9 #define Max 50005
    10 
    11 int army[Max], n;
    12 
    13 int lowbit(int i)
    14 {
    15     return i&(-i);
    16 }
    17 
    18 void Change(int i, int x)
    19 {
    20     while (i <= n)
    21     {
    22         army[i] += x;
    23         i += lowbit(i);
    24     }
    25     return ;
    26 }
    27 
    28 int sadd(int i)
    29 {
    30     int sum = 0;
    31     while (i > 0)
    32     {
    33         sum += army[i];
    34         i -= lowbit(i);
    35     }
    36     return sum;
    37 }
    38 
    39 int main()
    40 {
    41     int i, j, x, t, bout = 1;
    42     char instruct[16];
    43     scanf("%d", &t);
    44     while (t--)
    45     {
    46         memset(army, 0, sizeof(army));
    47         scanf("%d", &n);
    48         for (i = 1; i <= n; i++)
    49         {
    50             scanf ("%d", &x);
    51             Change(i, x);
    52         }
    53         printf ("Case %d:\n", bout ++);
    54         while (scanf("%s", instruct))
    55         {
    56             if (instruct[0] == 'E')
    57                 break ;
    58             scanf ("%d%d",&i, &j);
    59             if (instruct[0] == 'A')
    60                 Change(i, j);
    61             else if (instruct[0] == 'S')
    62                 Change(i, -j);
    63             else printf("%d\n",sadd(j) - sadd(i - 1));
    64         }
    65     }
    66     return 0;
    67 
    68 }

    线段树解题代码:

    View Code
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<string.h>
      5 using namespace std;
      6 class Node
      7 {
      8 public:
      9     int l,r,mid;
     10     int count;    
     11 };
     12 Node tree[200024];
     13 int num[50024];
     14 class Tree
     15 {
     16 public:
     17       void Maketree( int l,int r,int cnt );
     18       void Add( int l,int r, int cnt);
     19       int Qestion( int l,int r,int cnt );    
     20 };
     21 void Tree::Maketree( int l,int r,int cnt )
     22 {
     23     if( l == r )
     24     {
     25         tree[cnt].l = tree[cnt].r = l;
     26         tree[cnt].mid = l;
     27         tree[cnt].count = num[l];    
     28         return ;
     29     }    
     30     else
     31     {
     32         tree[cnt].l = l;
     33         tree[cnt].r = r;
     34         tree[cnt].mid = ( l + r )>>1;
     35         Maketree( l , tree[cnt].mid , cnt*2 );
     36         Maketree( tree[cnt].mid +1 , r, cnt*2 +1 );
     37         tree[cnt].count = tree[cnt*2].count + tree[cnt*2+1].count;
     38     }
     39 }
     40 void Tree::Add( int n,int m, int cnt )
     41 {
     42      if( tree[cnt].l == n&&tree[cnt].r==n )
     43      {
     44           tree[cnt].count += m;
     45           return;        
     46      }    
     47      else
     48      {
     49          if( n > tree[cnt].mid )
     50          Add( n , m , cnt*2+1 );
     51          else Add( n , m ,cnt*2 );        
     52          tree[cnt].count += m; 
     53      }
     54 }
     55 int Tree::Qestion( int l,int r,int cnt )
     56 {
     57    if( l==tree[cnt].l&&r==tree[cnt].r )
     58       return tree[cnt].count;
     59    else
     60    {
     61        if( l > tree[cnt].mid )
     62          return Qestion( l, r, cnt*2+1 );
     63        else
     64        {
     65             if( r <= tree[cnt].mid )
     66               return Qestion( l , r ,cnt*2 );
     67             else
     68             {
     69                return Qestion( l , tree[cnt].mid, cnt*2 )+Qestion( tree[cnt].mid+1,r, cnt*2+1 );    
     70             }        
     71        }        
     72    }    
     73 }
     74 int main( )
     75 {
     76    int Case,n,l,r;
     77    char c[10];
     78    while( scanf( "%d",&Case )==1 )
     79    {
     80       Tree e;
     81       for( int i=1; i<=Case ; i++ )
     82       {
     83           printf( "Case %d:\n",i );
     84           scanf( "%d",&n );
     85           for( int j=1; j<= n; j++ )
     86             scanf( "%d",&num[j] );    
     87           e.Maketree( 1,n,1 );
     88           while( scanf( "%s",c ),c[0]!='E' )
     89           {
     90              scanf( "%d%d",&l,&r );
     91               if( c[0]=='A' )
     92                e.Add( l,r,1 );
     93               else if( c[0]=='S' ) 
     94                    e.Add( l , -1*r,1 );
     95               else printf( "%d\n",e.Qestion( l,r,1 ) );        
     96           }    
     97       }        
     98    }
     99    return 0;    
    100 }
  • 相关阅读:
    【有感】向香港雷锋学什么
    After NeuSoft’s Interview
    【SHELL学习】if语句
    《我是一只IT小小鸟》【1】
    MSDN微软社区 大连线下聚会 即将举行
    【毕业设计】修改用户信息
    SQL Connection
    EasyPR中文开源车牌识别系统 开发详解(1)
    EasyPR开发详解(2)车牌定位
    EasyPR开发详解(4)形态学操作、尺寸验证、旋转等操作
  • 原文地址:https://www.cnblogs.com/shengshouzhaixing/p/2974020.html
Copyright © 2011-2022 走看看