[HDU]1166敌兵布阵<静态线段树>
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
题目大意:给出n个点,每个点有一个值,现在有三种操作,
1.在i点加上j
2.在i点减去j
3.查询i,j区间总和
这其实是一道非常裸的线段树,但是我还是卡了好久,结果最后发现竟然是自己的freopen和代码习惯惹的祸。这道题我用了两种方法,一种是比较常规的版本,一种是不用结构体的静态树
首先来看一个常规的代码(带结构体)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<stack>
#define maxn 500005
#define lson pos<<1
#define rson pos<<1|1
using namespace std; struct node{
int l,r,sum;
}e[maxn]; int n,a[maxn],t; void build(int l,int r,int pos)
{
e[pos].l=l;e[pos].r=r;
if(l==r)e[pos].sum=a[l];
else{
int mid=(l+r)>>;
build(l,mid,lson);build(mid+,r,rson);
e[pos].sum=e[lson].sum+e[rson].sum;//pushup操作
}
} void add(int k,int x,int pos)
{
int l=e[pos].l,r=e[pos].r;
e[pos].sum+=x;
int mid=(l+r)>>;
if(l==r&&l==k)
{
return;
}else{
if(k<=mid)add(k,x,lson);
else add(k,x,rson);
}
} void sub(int k,int x,int pos)
{
e[pos].sum-=x;
int l=e[pos].l;int r=e[pos].r;
int mid=(l+r)>>;
if(l==r&&l==k)
{
return;
}else{
if(k<=mid)sub(k,x,lson);
else sub(k,x,rson);
}
} int summ;
void query(int l,int r,int pos)
{
if(e[pos].l>=l&&e[pos].r<=r){
summ+=e[pos].sum;
}
else{
int mid=(e[pos].l+e[pos].r)/;
if(mid>=r){
query(l,r,lson);
}
else{
if(l>mid)query(l,r,rson);
else{
query(l,r,lson);query(l,r,rson);
}
}
}
} char ch[];
int main()
{
scanf("%d",&t);int y=;
while(t--)
{
y++;
printf("Case %d:\n",y);
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
scanf("\n");
build(,n,); while()
{ scanf("%s",ch);
if(ch[]=='E')break;
if(ch[]=='A'){
int x,y;
scanf("%d%d",&x,&y);
add(x,y,);
}
if(ch[]=='S')
{
int x,y;
scanf("%d%d",&x,&y);
sub(x,y,);
}
if(ch[]=='Q')
{ summ=;
int x,y;
scanf("%d%d",&x,&y);
query(x,y,);
printf("%d\n",summ);
} } }
}
打完这个代码其实不难发现,每一个pos(节点)的左右区间其实是固定的,而且还可以推出来,画个图分析一下

红色数字为pos,黑色为l,r,可以发现其实pos对应的l,r不会变,就是一棵静态树,
所以我们就可以不用结构体,只用看一个sum数组就可以解决了
来看一看代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define lson pos<<1
#define rson pos<<1|1
#define maxn 500005
using namespace std; int sum[maxn<<];
int a[maxn],n,m,t;
char ch[]; void pushup(int pos)
{
sum[pos]=sum[lson]+sum[rson];
} void build(int l,int r,int pos)
{
if(l==r){sum[pos]=a[l];return;}
int mid=(l+r)/;
build(l,mid,lson);
build(mid+,r,rson);
pushup(pos);
} void add(int k,int x,int pos,int l,int r)
{
if(l==r){sum[pos]+=x;return;}
int mid=(l+r)>>;
if(k<=mid)add(k,x,lson,l,mid);
else add(k,x,rson,mid+,r);
pushup(pos);
} void sub(int k,int x,int pos,int l,int r)
{
if(l==r){sum[pos]-=x;return;}
int mid=(l+r)>>;
if(k<=mid)sub(k,x,lson,l,mid);
else sub(k,x,rson,mid+,r);
pushup(pos);
} int query(int al,int ar,int l,int r,int pos)
{
if(al<=l&&r<=ar)return sum[pos];
int mid=(l+r)>>,s=;
if(al<=mid)s+=query(al,ar,l,mid,lson);
if(ar>mid) s+=query(al,ar,mid+,r,rson);
return s;
} int main()
{
scanf("%d",&t);int y=;
while(t--)
{
cout<<"Case "<<++y<<":"<<endl;
memset(sum,,sizeof(sum));
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
build(,n,);
while()
{
scanf("%s",ch);
int x,y;
if(ch[]=='E')break;
if(ch[]=='A'){
scanf("%d%d",&x,&y);
add(x,y,,,n);
}
if(ch[]=='S')
{
scanf("%d%d",&x,&y);
sub(x,y,,,n);
}
if(ch[]=='Q')
{
scanf("%d%d",&x,&y);
printf("%d\n",query(x,y,,n,));
}
}
}
}
PS:诸位OIer打代码特别是函数时要注意声明的左右点和pos的位置关系,要一一对应,不然就像我一样会调试一天
[HDU]1166敌兵布阵<静态线段树>的更多相关文章
- hdu 1166敌兵布阵(线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) M ...
- hdu 1166 敌兵布阵 (线段树单点更新)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 1166 敌兵布阵(线段树/树状数组模板题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- HDU 1166——敌兵布阵——————【线段树单点增减、区间求和】
敌兵布阵 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status ...
- HDU 1166 敌兵布阵 【线段树-点修改--计算区间和】
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 1166 敌兵布阵(线段树区间求和)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU 1166 敌兵布阵(线段树模板题)
题目链接: 传送门 敌兵布阵 Time Limit: 2000MS Memory Limit: 32768 K Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头 ...
- hdu 1166 敌兵布阵【线段树】(求给定区间和)
题目链接:https://vjudge.net/contest/182746#problem/B 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 1166 敌兵布阵 (线段树模版题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
随机推荐
- 2020年,如何成为一名 iOS 开发高手!
2020年对应程序员来说,是一个多灾的年份,很多公司都进行了不同比例的优化和裁员.等疫情得到控制后,将会是找工作的高峰期,从去年的面试经历来看,现在只会单纯写业务代码的人找工作特别难,很多大厂的面试官 ...
- 自己查与写的批量比较bash
前言:互测的时候一个一个输入感觉太麻烦,于是尝试写自己的对拍,又想到os刚学了bash命令行处理,于是想把两者结合一下减轻自己的工作量 分两步: 将所有人的工程导出成jar文件 放到linux下用ba ...
- 第一个Hystrix程序 Hystrix 一
1.导入jar包 <dependencies> <dependency> <groupId>com.netflix.hystrix</groupId> ...
- java线程间的共享
本次内容主要讲synchronized.volatile和ThreadLocal. 1.synchronized内置锁 线程开始运行,拥有自己的栈空间,就如同一个脚本一样,按照既定的代码一步一步地执行 ...
- JS中的reduce()详解
reduce()作为一个循环使用.接收四个参数:初始值(上一次返回值),当前元素值,当前元素下标,原数组. 应用 作为累加器使用 var a=[4,5,6,7,8] //item代表一次回调的值 初 ...
- PHP eval变量延迟赋值
$str = 'and {$prev}name like \'%五子棋%\'';$prev = "table.";eval("\$str = \"$str\&q ...
- Asp.Net Core 2.0实现HttpResponse中繁切换
随笔背景:因为项目中有个简单的功能是需要实现中文简体到繁体的切换,数据库中存储的源数据都是中文简体的,为了省事就想着通过HttpHeader的方式来控制Api返回对应的繁体数据. 实现方式:通过Asp ...
- RocketMQ-2.RocketMQ的负载均衡
目录 RocketMQ的负载均衡 producer对MessageQueue的负载均衡 producer负载均衡 系统计算路由MessageQueue 自定义路由MessageQueue Consum ...
- 今天对C语言不常用的小东西的了解
今天又翻了C语言的书,看到const语句,一时间想不起来到底是干嘛的,看语句const int a=1;明白了这是一个支持常量指定类型的定义常量的关键字,作用几乎与#define一毛一样,但# ...
- Java安装和配置
一. Java安装和配置 1.JDK下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-21331 ...