题目链接: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敌兵布阵<静态线段树>的更多相关文章

  1. hdu 1166敌兵布阵(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    M ...

  2. hdu 1166 敌兵布阵 (线段树单点更新)

    敌兵布阵                                                         Time Limit: 2000/1000 MS (Java/Others)  ...

  3. HDU 1166 敌兵布阵(线段树/树状数组模板题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  4. HDU 1166——敌兵布阵——————【线段树单点增减、区间求和】

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

  5. HDU 1166 敌兵布阵 【线段树-点修改--计算区间和】

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. hdu 1166 敌兵布阵(线段树区间求和)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  7. HDU 1166 敌兵布阵(线段树模板题)

    题目链接: 传送门 敌兵布阵 Time Limit: 2000MS     Memory Limit: 32768 K Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头 ...

  8. hdu 1166 敌兵布阵【线段树】(求给定区间和)

    题目链接:https://vjudge.net/contest/182746#problem/B       敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)   ...

  9. HDU 1166 敌兵布阵 (线段树模版题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. 7-43 jmu-python-字符串异常处理 (20 分)

    输入一行字符串及下标,能取出相应字符.程序能对不合法数据做相应异常处理. 输入格式: 行1:输入一字符串 行2:输入字符下标 输出格式: 下标非数值异常,输出下标要整数 下标越界,输出下标越界 数据正 ...

  2. CKEditor4.7怎样实现上传图片,浏览服务器(无需ckfinder),nodejs图片管理,字体居中,图片居中(超详细)

    首先是下载CKEditor,下载地址:http://ckeditor.com/download 选择里面的Customize自定义,如图 然后进入配置界面,第一个choose preset一般就选st ...

  3. web前端性能优化的技巧

    1. 请减少HTTP请求 基本原理: 在浏览器(客户端)和服务器发生通信时,就已经消耗了大量的时间,尤其是在网络情况比较糟糕的时候,这个问题尤其的突出. 一个正常HTTP请求的流程简述:如在浏览器中输 ...

  4. Javascript Event事件中IE与标准DOM的区别

    1.事件流的区别 <body> <div> <button>点击这里</button> </div> </body> IE采用冒 ...

  5. Hibernage错误:Could not open Hibernate Session for transaction

    今天客户发来的错误,是SSH框架做的项目,是用户在登陆时候出现的错误,但刷新之后就没问题. 提示错误:Could not open Hibernate Session for transaction. ...

  6. 阿里云上docker部署nginx实现反向代理

    简介   需要从镜像仓库找到所需要的nginx版本pull下来.(地址:https://hub.docker.com/) 1.docker pull nginx 1.挂载目录 1.1 获取nginx. ...

  7. 02 layui 下载和搭建环境

    Layui官方网站 官方网站:https://www.layui.com/ 下载地址:https://res.layui.com/static/download/layui/layui-v2.5.5. ...

  8. c++中比较好用的黑科技

    切入正题,上黑科技 一.黑科技函数(常用的我就不写了,例如sort函数) 1.next_permutation(a+1,a+1+n) a[1-n]全排列 2.reverse(a+1,a+1+n) 将a ...

  9. JAVAEE学习day05学习,数组

    容器及元素的概念 容器:是将多个数据存储到一起 元素:每个数据称为该容器的元素 数组的概念 数组:数组是长度固定,存储数据的容器,保证多个数据的类型要一致 数组定义格式及其描述 动态定义: 数据类型 ...

  10. Leetcode 1160: 拼写单词

    给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars. 假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌 ...