hdu 1166 树状数组(线段树)
敌兵布阵
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 35307 Accepted Submission(s): 14974
中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时向Derek汇报某一段连续的工兵营地一共有多少人,例如Derek问:“Tidy,马上汇报第3个营地到第10个营地共有多少人!”Tidy就要马上开始计算这一段的总人数并汇报。但敌兵营地的人数经常变动,而Derek每次询问的段都不一样,所以Tidy不得不每次都一个一个营地的去数,很快就精疲力尽了,Derek对Tidy的计算速度越来越不满:"你个死肥仔,算得这么慢,我炒你鱿鱼!”Tidy想:“你自己来算算看,这可真是一项累人的工作!我恨不得你炒我鱿鱼呢!”无奈之下,Tidy只好打电话向计算机专家Windbreaker求救,Windbreaker说:“死肥仔,叫你平时做多点acm题和看多点算法书,现在尝到苦果了吧!”Tidy说:"我知错了。。。"但Windbreaker已经挂掉电话了。Tidy很苦恼,这么算他真的会崩溃的,聪明的读者,你能写个程序帮他完成这项工作吗?不过如果你的程序效率不够高的话,Tidy还是会受到Derek的责骂的.
每组数据第一行一个正整数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条命令
对于每个Query询问,输出一个整数并回车,表示询问的段中的总人数,这个数保持在int以内。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int f[]; inline int lowbit(int x){ return x&(-x);}
inline void add(int x,int d,int n)
{
while(x<=n)
{
f[x]+=d;x+=lowbit(x);
}
} inline int sum(int x)
{
int ret=;
while(x>=)
{
ret+=f[x];x-=lowbit(x);
}
return ret;
}
int main()
{
int T,n,i,j,a,b,p;
char s[];
scanf("%d",&T);
for(i=;i<=T;i++)
{
scanf("%d",&n);
fill(f,f+n+,);
for(j=;j<=n;j++) scanf("%d",&p),add(j,p,n);
printf("Case %d:\n",i);
while(scanf("%s",s) && strcmp(s,"End")!=)
{
scanf("%d %d",&a,&b);
if(strcmp(s,"Add")==)
add(a,b,n);
else if(strcmp(s,"Sub")==)
add(a,-b,n);
else if(strcmp(s,"Query")==)
printf("%d\n",sum(b)-sum(a-));
}
}
return ;
}
线段树解法:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int a[]; struct IntervalTree
{
int left,right,sum;
}f[]; void bulid(int left,int right,int i)
{
int mid;
f[i].left=left;
f[i].right=right;
if(left==right)
{
f[i].sum=a[left];
return;
}
mid=(left+right)/;
bulid(left,mid,*i);
bulid(mid+,right,*i+);
f[i].sum=f[*i].sum+f[*i+].sum;
return ;
} void add(int x,int d,int i)
{
if(f[i].left==f[i].right)
{
f[i].sum+=d;
return ;
}
f[i].sum+=d;
if(x<=f[i*].right) add(x,d,*i);
else add(x,d,*i+);
return ;
} int query(int left,int right,int i)
{
int mid;
if(f[i].left==left && f[i].right==right) return f[i].sum;
mid=(f[i].left+f[i].right)/;
if(right<=mid) return query(left,right,i*);
else if(left>mid) return query(left,right,i*+);
else return query(left,mid,*i)+query(mid+,right,*i+);
} int main()
{
int T,n,i,j,lp,rp;
char s[];
scanf("%d",&T);
for(i=;i<=T;i++)
{
scanf("%d",&n);
for(j=;j<=n;j++) scanf("%d",a+j);
bulid(,n,);
printf("Case %d:\n",i);
while(scanf("%s",s) && strcmp(s,"End")!=)
{
scanf("%d %d",&lp,&rp);
if(strcmp(s,"Add")==)
add(lp,rp,);
else if(strcmp(s,"Sub")==)
add(lp,-rp,);
else if(strcmp(s,"Query")==)
printf("%d\n",query(lp,rp,));
}
}
return ;
}
hdu 1166 树状数组(线段树)的更多相关文章
- 树状数组 && 线段树应用 -- 求逆序数
参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...
- hdu1394(枚举/树状数组/线段树单点更新&区间求和)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...
- 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树
正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 5147 Sequence II【树状数组/线段树】
Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- hdu 1166 敌兵布阵——(区间和)树状数组/线段树
pid=1166">here:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Input 第一行一个整数T.表示有T组数据. 每组数据第一 ...
- HDU 1166 敌兵布阵 树状数组||线段树
http://acm.hdu.edu.cn/showproblem.php?pid=1166 题目大意: 给定n个数的区间N<=50000,还有Q个询问(Q<=40000)求区间和. 每个 ...
- hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...
- HDU 3303 Harmony Forever 前缀和+树状数组||线段树
Problem Description We believe that every inhabitant of this universe eventually will find a way to ...
随机推荐
- mohout安装
安装完成之后的环境变量的配置如下: JAVA_HOME=/usr/local/jdk1.8.0_144JRE_HOME=/usr/java/jdk1.8.0_144/jreCLASSPATH=.:$J ...
- 使用python模拟登陆百度
#!/usr/bin/python # -*- coding: utf- -*- """ Function: Used to demostrate how to use ...
- softmax_loss
softmax_loss中的ignore_label是来自于loss layer,而不是softmax_loss的参数
- touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied
docker 运行后, 执行docker logs -f myjenkins时报错: touch: cannot touch ‘/var/jenkins_home/copy_reference_fil ...
- dom事件机制系列
JS事件流机制 一个完整的JS事件流是从window开始,最后回到window的一个过程,事件流被分为三个阶段: (1~5)捕获过程.(5~6)目标过程.(6~10)冒泡过程. 通过addEventL ...
- CVS使用之:先update后commit
vcs在进行版本管理时: 1.如果添加新文件 cvs add directory_name/filename cvs commit directory_name/filename 2.如果修改文件 c ...
- perl:split函数用法
本文和大家重点讨论一下Perl split函数的用法,Perl中的一个非常有用的函数是Perl split函数-把字符串进行分割并把分割后的结果放入数组中.这个Perl split函数使用规则表达式( ...
- c++-string-1
解答注意: 我写的时候考虑了: 1) " my"(设置flag,为true时表示上一个是非空格字符) 2) "hello John"(最后不是空格结尾, ...
- cdev_add
初始化 cdev 后,需要把它添加到系统中去.为此可以调用 cdev_add()函数.传入cdev 结构的指针,起始设备编号,以及设备编号范围. 函数首先将分配的设备号与设备数目保存进cdev结构体中 ...
- python中os模块讲解
本文主要介绍一些os模块常用的方法: 先看下我的文件目录结构 D:\LearnTool\pycode\part1 在此目录下的文件如下: abcd.py demo1.1.py demo1.2.py z ...