HDU1166 敌兵布阵 线段树详解
题解:
更新是线段树的单点更新,简单一点。
有50000个阵营,40000查询,用普通数组肯定超时。区间求和和区间查询问题用线段树最好不过了。
先说说什么是线段树。
区间[1,10]用树的方法存起来,怎么存呢,来看下图:

线段树结构主要用于区间查询和更新。时间复杂度为lgN。虽然空间大了但时间快了。对于数据到达 亿 级别的,效果尤为显著。
知道了线段树的结构,那么怎么用代码实现建树,查询以及更新呢..看代码。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring> //杭电上 如果用c++编译器则改成incluce<string> ,c++编译器不支持cstring不知道为啥。 using namespace std; //这道题建议用G++编译器提交 const int MAX=50001; typedef struct node //定义树节点
{
node(){l=0,r=0,data=0;} //构造函数
int l,r; //区间[l,r]
int data; //数据,这里指区间[l,r]的和
}TreeNode; TreeNode treeNode[MAX<<4];
int a[MAX]; void update(int p) //向上更新
{
treeNode[p].data=treeNode[p*2].data+treeNode[p*2+1].data;
} void buildTree(int p,int l,int r) //建树,p是节点编号,从1开始,l,r是区间
{
treeNode[p].l=l;
treeNode[p].r=r; if(l==r) //如果是叶子节点,则赋值 返回
{
treeNode[p].data=a[l];
return;
}
int mid=(l+r)>>1; //
buildTree(p<<1,l,mid); //递归地创建左子树和右子树 p<<1 <==> p*2
buildTree(p<<1|1,mid+1,r); // p<<1|1 <==> p*2+1
update(p); //回溯的时候更新data值
return;
} void add(int p,int k,int x) //添加方法,p节点编号(索引),k为要修改的区间[k,k],x为要修改的值
{
if(treeNode[p].l==k&&treeNode[p].r==k) //如果找到区间[k,k]
{
treeNode[p].data+=x;
return;
}
int mid=(treeNode[p].l+treeNode[p].r)/2;
if(k<=mid) add(p<<1,k,x); //如果要修改的点在当前区间的左边,查找左子树
else add(p<<1|1,k,x); //如果要修改的点在当前区间的右边,在右子树里查找
update(p); //回溯的时候更新data信息
return;
} int query(int p,int l,int r) //p为节点编号,查询区间[l,r];
{
if(treeNode[p].l>=l&&treeNode[p].r<=r) //如果当前节点的区间在[l,r]内
{
return treeNode[p].data;
}
if(treeNode[p].l>r||treeNode[p].r<l) //如果当前区间和要查找的区间没有交集
{
return 0;
}
int sum=0;
sum+=query(p<<1,l,r); //查询左子树
sum+=query(p<<1|1,l,r); //查询右子树
return sum;
} int main()
{
int n,tt; //区间[1,n],有tt组测试数据
//cin>>tt; //测试数据 输入就有 40000+,用cin就超时,scanf秒过,或者能用scanf的就用scanf
scanf("%d",&tt);
for(int t=1;t<=tt;t++)
{
//cin>>n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
//cin>>a[i];
scanf("%d",&a[i]);
}
buildTree(1,1,n); //建树,节点编号从1开始,区间[1,n] string op; //操作 printf("Case %d:\n",t); while(cin>>op) //string 类型只能用cin输入
{
if(op=="Query")
{
int a,b;
//cin>>a>>b;
scanf("%d%d",&a,&b);
//cout<<query(1,a,b)<<endl;
printf("%d\n",query(1,a,b));
continue;
}
if(op=="Add")
{
int a,b;
//cin>>a>>b;
scanf("%d%d",&a,&b);
add(1,a,b);
continue;
}
if(op=="Sub")
{
int a,b;
//cin>>a>>b;
scanf("%d%d",&a,&b);
add(1,a,-b);
continue;
}
if(op=="End")
{
break;
}
} }
return 0;
}
HDU1166 敌兵布阵 线段树详解的更多相关文章
- hdu 1166 敌兵布阵(线段树详解)
Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任 ...
- HDU-1166敌兵布阵(线段树)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submissi ...
- hdu1166 敌兵布阵(线段树 求区间和 更新点)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- hdu1166 敌兵布阵 线段树(区间更新)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU1166 敌兵布阵(线段树)
C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...
- 【生活没有希望】hdu1166敌兵布阵 线段树
线段树水题刷刷,生活没有希望 最近看到代码跟树状数组差不多短的非递归线段树,常数也很小——zkw线段树 于是拿道水题练练手 短到让人身无可恋 ;pos;pos/=) a[pos]+=x;} ,ans= ...
- HDU1166 敌兵布阵 —— 线段树单点修改
题目链接:https://vjudge.net/problem/HDU-1166 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布 ...
- HDU1166 敌兵布阵 [线段树模板]
题意:在序列中修改单点和查询区间和 #include<iostream> #include<cstdio> #include<cstring> #define ls ...
- HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)
HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...
随机推荐
- 【leecode】宝石与石头
给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J 中的字母不重复,J 和 S中的所有字符都是字母 ...
- el7上的开机自动执行脚本
/etc/rc.local 是 /etc/rc.d/rc.local的软连接 默认, /etc/rc.local 是有可执行权限的, 只要 给 /etc/rc.d/rc.local 加上可执行权限即可 ...
- mDNS 原理的简单理解
转自:http://www.binkery.com/post/318.html mDNS 原理的简单理解 mDNS multicast DNS , 使用5353端口. 在局域网内,你要通过一台主机和其 ...
- Project Euler 28 Number spiral diagonals
题意:给出一个 1001 × 1001 的矩阵,寻找每一圈四个顶点,并求出所有顶点的和 思路:只需要找到右上顶点数字的规律,然后每一圈四个顶点构成了一个等差数列,求个和即可 /************ ...
- Ural 1996 Cipher Message 3 (生成函数+FFT)
题面传送门 题目大意:给你两个$01$串$a$和$b$,每$8$个字符为$1$组,每组的最后一个字符可以在$01$之间转换,求$b$成为$a$的一个子串所需的最少转换次数,以及此时是从哪开始匹配的. ...
- BZOJ 3144 [HNOI2013]切糕 (最大流+巧妙的建图)
题面:洛谷传送门 BZOJ传送门 最大流神题 把点权转化为边权,切糕里每个点$(i,j,k)$向$(i,j,k+1)$连一条流量为$v(i,j,k)$的边 源点$S$向第$1$层的点连边,第$R+1$ ...
- keepalived实现IP地址高可用
yum -y install keepalived vim /etc/keepalived/keepalived.conf global_defs { router_id LVS_DEVEL_ngin ...
- BA-Honeywell WEBsAX系统
- Grand Central Dispatch(GCD)详解
概述 GCD是苹果异步执行任务技术,将应用程序中的线程管理的代码在系统级中实现.开发者只需要定义想要执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并计划执行任务.由于 ...
- Android Cursor浅析
1. 本文目的 Android ContentProvider提供了进程间数据交换的一种机制.而数据库的查询就是这样的机制的应用.那么app通过Uri查询数据库而得到的Cursor到底是个什么东西?为 ...