题目大意: 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. cf492B Vanya and Lanterns

    B. Vanya and Lanterns time limit per test 1 second memory limit per test 256 megabytes input standar ...

  2. 解决Jenkins上git出现Timeout的问题

    Jenkins上现有的git插件并没有配置超时的选项,因此在clone项目时如果网络差会出现“ERROR: Timeout after 10 minutes”,导致无法继续构建. 网上找到一个解决方法 ...

  3. <转载>无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用

    转载http://blog.sina.com.cn/s/blog_6e6c5f230100p92p.html 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引 ...

  4. 关于matlab中textread

    本文主要内容引自http://linux.chinaitlab.com/administer/872894.html 笔者在此基础上进行运行,修改得到以下内容,希望大家给与补充: textread 基 ...

  5. ViewPager顶部标题控件PagerSlidingTabStrip

    最近搞一个项目,要求做一个和网易新闻顶部菜单的滑动效果,如图: 顶部标题中下面有个红色的矩形小条,左右滑动时会跟随手势动态滑动,效果很绚丽,唉,特效啊! 自己搞了一上午无果,还是是github上找大神 ...

  6. Makefile学习(二)条件判断和内嵌函数

    第七章:Makefile的条件执行 条件语句可是是两个不同的变量.或者变量和常量值的比较: 7.1例子: 对变量“CC”进行判断,其值如果是“gcc ”那么在程序连接时使用库“libgnu.so”或者 ...

  7. HDU--1584--蜘蛛牌--深搜版本号

    蜘蛛牌 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  8. QT实现透明效果的按钮

    QPushButton { color: rgb(0,88,152) background-color: rgba(97%,80%,9%,50%)}

  9. 货币小写转大写.htm

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. POJ 1001 Exponentiation 模拟小数幂

    模拟小数幂 小数点位 pos 非零末位 e 长度 len 只有三种情况 pos > len pos < e e < pos < len #include <iostrea ...