HDU 1540 Tunnel Warfare (线段树)
题目大意: n 个村庄排列在一条直线上,相邻的村庄有地道连接,除首尾两个村庄外,其余村庄都有两个相邻的村庄。其中有 3 中操作 D x :表示摧毁编号为 x 的村庄,Q x:表示求出包含村庄 x 的最长区间中村庄的数目,R 表示修复最后摧毁的村庄。输入 n,m 分别表示村庄的树木,和操作的次数。
思路 : 当查询包含 村庄 x 的最长区间的村庄数时,可以求出位于 区间 [1,x-1] 中被摧毁的最大村庄编号,求出[x+1,n] 中被摧毁的最小村庄的编号。由此便可求出结果。
可利用线段树存储区间内的被摧毁的村庄的最大和最小编号。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
#define INF 100000000
int n,m;
struct node{
int l;
int r;
int MAX;
int MIN;
}a[201000];
void buildtree(int i,int l,int r){
a[i].l = l ;
a[i].r = r ;
a[i].MAX = -INF ;
a[i].MIN = INF ;
if(l == r)
return ;
int mid = (l+r)/2;
buildtree(i*2,l,mid);
buildtree(i*2+1,mid+1,r);
}
void Destory(int i,int x){
a[i].MAX = max(a[i].MAX,x);
a[i].MIN = min(a[i].MIN,x);
if(a[i].l == a[i].r)
return ;
int mid = (a[i].l + a[i].r) / 2;
if(x <= mid)
Destory(i*2,x);
else
Destory(i*2+1,x);
}
int Querymax(int i,int l,int r){
if(a[i].l == l && a[i].r == r){
return a[i].MAX ;
}
if(a[i].l == a[i].r)
return a[i].MAX;
int ans = -INF;
int mid = (a[i].l + a[i].r) / 2 ;
if(r <= mid)
ans = Querymax(i*2,l,r);
else if(l > mid)
ans = Querymax(i*2+1,l,r);
else{
ans = max(ans,Querymax(i*2,l,mid));
ans = max(ans,Querymax(i*2+1,mid+1,r));
}
return ans ;
}
int Querymin(int i,int l,int r){
if(a[i].l == l && a[i].r == r)
return a[i].MIN ;
if(a[i].l == a[i].r)
return a[i].MIN;
int ans = INF ;
int mid = (a[i].l + a[i].r) / 2 ;
if(r <= mid)
ans = Querymin(i*2,l,r) ;
else if(l > mid)
ans = Querymin(i*2+1,l,r) ;
else{
ans = min(ans,Querymin(i*2,l,mid));
ans = min(ans,Querymin(i*2+1,mid+1,r));
}
return ans ;
}
void rebuild(int i,int x){
if(a[i].l == a[i].r){
a[i].MAX = -INF ;
a[i].MIN = INF ;
return ;
}
int mid = (a[i].l + a[i].r) / 2 ;
if(x <= mid)
rebuild(i*2,x);
else
rebuild(i*2+1,x);
a[i].MAX = max(a[i*2].MAX,a[i*2+1].MAX);
a[i].MIN = min(a[i*2].MIN,a[i*2+1].MIN);
}
int main(){
char op;
int x,sum,top,stack[50000];
while(~scanf("%d%d",&n,&m)){
buildtree(1,1,n);
top = 0;
for(int k=1;k<=m;k++){
getchar();
scanf("%c",&op) ;
if(op == 'D'){
scanf("%d",&x);
stack[top++] = x ;
Destory(1,x);
}
else if(op == 'Q'){
scanf("%d",&x);
int ans1 = Querymax(1,1,x);
int ans2 = Querymin(1,x,n);
if(ans1==x || ans2==x)
printf("0\n");
else {
if(ans1 == -INF)
sum = x - 1 ;
else
sum = x - ans1 - 1 ;
if(ans2 == INF)
sum += n - x ;
else
sum += ans2 - 1 - x;
sum ++ ;
printf("%d\n",sum);
}
}
else if(op == 'R'){
if(top > 0)
rebuild(1,stack[--top]);
}
}
}
return 0;
}
HDU 1540 Tunnel Warfare (线段树)的更多相关文章
- hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
Tunnel Warfare Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 1540 Tunnel Warfare 线段树区间合并
Tunnel Warfare 题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少 思路:一个节点的最大连续区间由(左儿子的最大的连续区间,右儿子的最大连续区 ...
- hdu 1540 Tunnel Warfare(线段树区间统计)
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- HDU 1540 Tunnel Warfare (线段树)
Tunnel Warfare Problem Description During the War of Resistance Against Japan, tunnel warfare was ca ...
- HDU 1540 Tunnel Warfare (线段树或set水过)
题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少. 析:首先可以用set水过,set用来记录每个被破坏的村庄,然后查找时,只要查找左右两个端点好. 用线段 ...
- hdu 1540 Tunnel Warfare 线段树 区间合并
题意: 三个操作符 D x:摧毁第x个隧道 R x:修复上一个被摧毁的隧道,将摧毁的隧道入栈,修复就出栈 Q x:查询x所在的最长未摧毁隧道的区间长度. 1.如果当前区间全是未摧毁隧道,返回长度 2. ...
- hdu 1540 Tunnel Warfare 线段数区间合并
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) P ...
- HDU 1540 Tunnel Warfare(最长连续区间 基础)
校赛,还有什么途径可以申请加入ACM校队? Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/ ...
- hdu 1540 Tunnel Warfare (区间线段树(模板))
http://acm.hdu.edu.cn/showproblem.php?pid=1540 Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) ...
随机推荐
- swift 随机数
1.一行代码生成随机数 arc4random() 如果要生成一个生成在一定范围内的随机整数: func randomIn(#min: Int, max: Int) -> Int { retur ...
- Spring redirect直接返回项目根文件夹
return "redirect:/";
- SegmentFault 巨献 1024 程序猿游戏「红岸的呼唤」第三天任务攻略
第三关也不是一般的难呐,那么继续写一下解题过程(第四关会是什么样呢?). 高速传送门:http://segmentfault.com/game/3 在用我想到的方法(booth算法.矩阵变换.各种CP ...
- linux下单独安装oracle12.1客户端
1.安装oracle-instantclient:(默认安装即可) oracle-instantclient12.1-sqlplus-12.1.0.1.0-1.x86_64.rpmoracle-ins ...
- js获取浏览器滚动条距离顶端的距离
最近在做项目的时候遇到需要用js获取滚动条距离窗口顶端的距离和js获取浏览器可视化窗口的大小,在这儿做一个整理保存: 一.jQuery获取的相关方法 jquery 获取滚动条高度 获取浏览器显示 ...
- (转)@@trancount解析
在处理事务的时候,一般都用RollBack Transaction来回滚,但是如果在嵌套事务中这样使用的话,就会出现错误. 在SqlServer里,嵌套事务的层次是由@@TranCount全局变量反映 ...
- 0130——UIScrollView
1.contentSize幕布实际大小决定滚动的方向,如果小于图片本身不滚动,默认也是不滚动 view.contentSize = CGSizeMake(1280, 200); 而frame只是用来显 ...
- 通过 sp_configure 进行 Database Mail 配置
通过 sp_configure 进行 Database Mail 配置 直接执行步骤一. 如果报错,则先执行步骤二,再执行步骤一. 一. sp_configre ; GO RECONFIGURE; G ...
- 基于'sessionStorage'与'userData'的类session存储
Storage.js: 注意:此版本实现的存储在符合Web存储标准(ie8及ie8以上的版本与其他主流浏览器)的情况下与session的周期一致,但在页面不关闭的情况下没有过期时间,ie7及以下版本则 ...
- OpenGL ES 2.0 摄像机与投影
1.摄像机的设置 摄像机的位置坐标 摄像机的位置 摄像机up方向 Matrix.setLookAtM( mVMatrix, //存储生成矩阵元素的float[]类型数组 0, //填充起始偏移量 cx ...