敌兵布阵

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 68824    Accepted Submission(s): 28945

Problem 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
题目大意:给你一个数组,a[i]代表第i个军营的士兵数,现在需要实现以下功能,给你任意一个区间[a,b],让你快速输出这些军营一共有多少士兵,
还有可能执行某个军营士兵增加或减少的指令,指令非常多,足有四万个,军营数目也非常多,暴力做肯定死,这时候就要用到一种高效的数据结构
——线段树,可以高效的进行查询,更改,此题用基本的线段树就可以过,昨天刚学了线段树,所以就用了那个比较固定的模板,还不是很熟练,明早
再手敲一次。(呲牙)
代码:
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const int maxn=+;
int a[maxn],tree[*maxn];
int kase=;
void build(int p,int l,int r)//建树函数,p代表节点编号,l代表左边界,r代表右边界
{
if(l==r) {tree[p]=a[l];return;}
int mid=(l+r)/;
build(p<<,l,mid);//先建左子树
build((p<<)+,mid+,r);//后建右子树
tree[p]=tree[p<<]+tree[(p<<)+];//给出了子节点与父节点之间的关系,视具体问题改;
}
void change(int p,int l,int r,int x,int num)//p,l,r意思同上,x代表的是要改变的数的位置,num则是改变的值
{
if(l==r) {tree[p]+=num;return;}//找到该叶子节点,改变值,结束函数
int mid=(l+r)/;//二分查找
if(x<=mid) change(p<<,l,mid,x,num);//搜左子树
else change((p<<)+,mid+,r,x,num);
tree[p]=tree[p<<]+tree[(p<<)+];//叶子节点的值改变,其上的根节点的值也要在回溯时改变
}
int find(int p,int l,int r,int x,int y)//x代表查找区间的左边界,y代表查找区间的右边界,find函数的目的是获得一个值
{
if(x<=l&&r<=y) return tree[p];
int mid=(l+r)/;
if(y<=mid) return find(p<<,l,mid,x,y);
if(x>mid) return find((p<<)+,mid+,r,x,y);
else return (find(p<<,l,mid,x,mid)+find((p<<)+,mid+,r,mid+,y));
}
int main()
{
int T,i;
scanf("%d",&T);
char s[];
int c,d;
while(T--)
{
int n;
scanf("%d",&n);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
build(,,n);
printf("Case %d:\n",++kase);
while()
{
scanf("%s",s);
if(!strcmp(s,"End")) break;
scanf("%d%d",&c,&d);
if(!strcmp(s,"Add"))
{
change(,,n,c,d);
}
if(!strcmp(s,"Sub"))
{
change(,,n,c,-d);
}
if(!strcmp(s,"Query"))
{
printf("%d\n",find(,,n,c,d));
}
}
}
return ;
}

hdu1166 经典线段入门的更多相关文章

  1. ZOJ - 1610 经典线段树染色问题

    这个是一个经典线段树染色问题,不过题目给的是左右左右坐标,即[0,3]包含0-1这一段 1-2这一段 2-3这一段,和传统的染色不太一样,不过其实也不用太着急. 我们把左边的坐标+1,即可,那么[0, ...

  2. 经典Spring入门基础教程详解

    经典Spring入门基础教程详解 https://pan.baidu.com/s/1c016cI#list/path=%2Fsharelink2319398594-201713320584085%2F ...

  3. HDU1166(线段树 +更新单点,求区间总和)、HDU1754(线段树 + 更新单点,求区间最大值)

    线段树简单应用 先附上几张图便与理解,大佬文章传送门1.传送门2 HDU1166:题目描述 线段树 +更新单点,求区间总和 代码如下(递归版) #include<iostream> #in ...

  4. 网络流最经典的入门题 各种网络流算法都能AC。 poj 1273 Drainage Ditches

    Drainage Ditches 题目抽象:给你m条边u,v,c.   n个定点,源点1,汇点n.求最大流.  最好的入门题,各种算法都可以拿来练习 (1):  一般增广路算法  ford() #in ...

  5. UVA 674 Coin Change 换硬币 经典dp入门题

    题意:有1,5,10,25,50五种硬币,给出一个数字,问又几种凑钱的方式能凑出这个数. 经典的dp题...可以递推也可以记忆化搜索... 我个人比较喜欢记忆化搜索,递推不是很熟练. 记忆化搜索:很白 ...

  6. hdu1166(线段树)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 线段树功能:update:单点增减 query:区间求和 #pragma comment(lin ...

  7. hdu-1166(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 思路:线段树模板 #include<iostream> #include<cs ...

  8. poj-2828 Buy Tickets(经典线段树)

    /* Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 10207 Accepted: 4919 Descr ...

  9. pku 2777(经典线段树染色问题)

    Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41202   Accepted: 12458 Des ...

随机推荐

  1. hdu5348 MZL's endless loop(欧拉回路)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud MZL's endless loop Time Limit: 3000/1500 ...

  2. Couchbase 使用方法

    1.数据流向 List<模型>  数据-->MsgPack 打包成byte[]-> couchbase 实例调用 Store(Enyim.Caching.Memcached.S ...

  3. 小安,今天学会了MySQL中查询时间的方法哦

  4. JQuery中parents和closest的区别

    jquery中查找上层元素一般都习惯了用parents方法,往往忽略了还有一个效率更高的closest方法,看下w3cschool的解释 过程不一样,closest是找到一个即停止,而parents将 ...

  5. vi 编辑器初步

    vi 编辑器初步 4,vi进入后是命令模式 ,可以用i o s 进入插入模式 i ,在当前字符位置插入,o为新开一行插入,s删除当前字符添加 5,r 为直接替换当前字符 6,到行头按0,$为到行尾到未 ...

  6. 使用QtCreator作为ROS调试器

    如果你用过QtCreator,你一定会喜欢上它. 流畅的速度,强大的功能,优雅的外观,友好的界面,一切让人如此舒服.而且它支持从命令行作为调试器启动,只需加上-debug exe即可. 因此我想如果能 ...

  7. [HDU] 2094 产生冠军(拓扑排序+map)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2094 注意每组数据处理前,map要清空. #include<cstdio> #includ ...

  8. 设置Ubuntu Mysql可以远程链接

    1:修改my.cnf配置文件 $sudo vim /etc/mysql/my.cnf 修改为: bind-address = 0.0.0.0 2:进行授权操作 mysql> grant all ...

  9. HttpAsyncClient 的简单使用

    下载地址:http://hc.apache.org/downloads.cgi 在NetBeans中导入以下jar文件: 1:一次请求: public static void oneReuest(){ ...

  10. 在 Azure 虚拟机上部署反恶意软件解决方案

    本博客文章由我和我的同事 Sung Hsueh 共同撰写,Sung Hsueh 是 Microsoft Azure 计算部负责安全事项的项目经理. 本博客文章为"虚拟机扩展程序"系 ...