题目大意: 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 (线段树)的更多相关文章

  1. hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并

    Tunnel Warfare Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

  2. HDU 1540 Tunnel Warfare 线段树区间合并

    Tunnel Warfare 题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少 思路:一个节点的最大连续区间由(左儿子的最大的连续区间,右儿子的最大连续区 ...

  3. hdu 1540 Tunnel Warfare(线段树区间统计)

    Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  4. HDU 1540 Tunnel Warfare (线段树)

    Tunnel Warfare Problem Description During the War of Resistance Against Japan, tunnel warfare was ca ...

  5. HDU 1540 Tunnel Warfare (线段树或set水过)

    题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少. 析:首先可以用set水过,set用来记录每个被破坏的村庄,然后查找时,只要查找左右两个端点好. 用线段 ...

  6. hdu 1540 Tunnel Warfare 线段树 区间合并

    题意: 三个操作符 D x:摧毁第x个隧道 R x:修复上一个被摧毁的隧道,将摧毁的隧道入栈,修复就出栈 Q x:查询x所在的最长未摧毁隧道的区间长度. 1.如果当前区间全是未摧毁隧道,返回长度 2. ...

  7. hdu 1540 Tunnel Warfare 线段数区间合并

    Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) P ...

  8. HDU 1540 Tunnel Warfare(最长连续区间 基础)

    校赛,还有什么途径可以申请加入ACM校队?  Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/ ...

  9. hdu 1540 Tunnel Warfare (区间线段树(模板))

    http://acm.hdu.edu.cn/showproblem.php?pid=1540 Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) ...

随机推荐

  1. swift 随机数

    1.一行代码生成随机数  arc4random() 如果要生成一个生成在一定范围内的随机整数: func randomIn(#min: Int, max: Int) -> Int { retur ...

  2. Spring redirect直接返回项目根文件夹

    return "redirect:/";

  3. SegmentFault 巨献 1024 程序猿游戏「红岸的呼唤」第三天任务攻略

    第三关也不是一般的难呐,那么继续写一下解题过程(第四关会是什么样呢?). 高速传送门:http://segmentfault.com/game/3 在用我想到的方法(booth算法.矩阵变换.各种CP ...

  4. linux下单独安装oracle12.1客户端

    1.安装oracle-instantclient:(默认安装即可) oracle-instantclient12.1-sqlplus-12.1.0.1.0-1.x86_64.rpmoracle-ins ...

  5. js获取浏览器滚动条距离顶端的距离

    最近在做项目的时候遇到需要用js获取滚动条距离窗口顶端的距离和js获取浏览器可视化窗口的大小,在这儿做一个整理保存:    一.jQuery获取的相关方法 jquery 获取滚动条高度 获取浏览器显示 ...

  6. (转)@@trancount解析

    在处理事务的时候,一般都用RollBack Transaction来回滚,但是如果在嵌套事务中这样使用的话,就会出现错误. 在SqlServer里,嵌套事务的层次是由@@TranCount全局变量反映 ...

  7. 0130——UIScrollView

    1.contentSize幕布实际大小决定滚动的方向,如果小于图片本身不滚动,默认也是不滚动 view.contentSize = CGSizeMake(1280, 200); 而frame只是用来显 ...

  8. 通过 sp_configure 进行 Database Mail 配置

    通过 sp_configure 进行 Database Mail 配置 直接执行步骤一. 如果报错,则先执行步骤二,再执行步骤一. 一. sp_configre ; GO RECONFIGURE; G ...

  9. 基于'sessionStorage'与'userData'的类session存储

    Storage.js: 注意:此版本实现的存储在符合Web存储标准(ie8及ie8以上的版本与其他主流浏览器)的情况下与session的周期一致,但在页面不关闭的情况下没有过期时间,ie7及以下版本则 ...

  10. OpenGL ES 2.0 摄像机与投影

    1.摄像机的设置 摄像机的位置坐标 摄像机的位置 摄像机up方向 Matrix.setLookAtM( mVMatrix, //存储生成矩阵元素的float[]类型数组 0, //填充起始偏移量 cx ...