题意:有n个村庄排成一列,相邻的村庄可以通信,炸毁则不可以通信,进行m个操作。3种操作,1.炸毁某村庄;2.修复上一个被炸毁的村庄;3.查询某个村庄能通信的村庄数(自己算一个)。

解题:求某个点左边扩散和右边扩散的区间和,没被炸毁就算1,炸毁则算0,用二分查找左边界和右边界,假设查询的点为x,则左边界是x-l+1=query(),右边界判断标准是r-x+1=query();两次二分log,查询query也是log,时间复杂度是O(n+m*log*log),限速2000ms,1600+ms,思路简单,勉强能过。

另外还有一个坑:一个村庄可以被多次炸毁,修复只需要一次就够了。

 #include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std; int n,m;
int a[];
int sum[*];
stack<int>sta; void build(int l,int r,int rt)
{
if(l==r)
{
sum[rt]=a[l];
return;
}
int mid=(l+r)/;
build(l,mid,rt*);
build(mid+,r,rt*+); sum[rt]=sum[rt*]+sum[rt*+];
} void update(int p,int c,int l,int r,int rt)
{
if(l==r)///到达叶节点,修改后返回
{
sum[rt]=sum[rt]+c;
return ;
}
int mid=(l+r)/;
///根据条件判断往左调用还是往右
if(p<=mid) update(p,c,l, mid, rt*);
else update(p,c,mid+, r, rt*+);
sum[rt] = sum[rt*] + sum[rt*+];
} int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)///在区间内,直接返回
return sum[rt]; int m=(l+r)/; ///累计答案
int ans=;
if(L<=m) ans=ans+query(L,R,l,m,rt*);
if(R>m) ans=ans+query(L,R,m+,r,rt*+); return ans;
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
while(!sta.empty())
sta.pop();
set<int>se;
for(int i=;i<=n;i++)
a[i]=;
build(,n,);
char c;
while(m--)
{
getchar();
scanf("%c",&c);
int x;
if(c=='D')
{
scanf("%d",&x);
if(a[x]!=)
update(x,-,,n,);
a[x]=;
sta.push(x);
}
else if(c=='R')
{
x=sta.top();
if( a[x]== );
else
{
while( a[x]!= )
{
sta.pop();
x = sta.top();
}
}
sta.pop();
a[x]=;
update(x,,,n,);
}
else
{
int ans=;
scanf("%d",&x); if(a[x]!=)
{
int l=,r=x,res1=-,res2=-;
while(l<=r)///往左找最大连通的村庄数
{
int mid=(l+r)/;
if( query(mid,x,,n,)==x-mid+ )///二分内往左找mid
{
res1=mid;
r=mid-; }
else///二分内往右找
{
l=mid+;
}
}
l=x,r=n;
while(l<=r)
{
int mid=(l+r)/; if( query(x,mid,,n,)==mid-x+ )
{
res2=mid;
l=mid+;
}
else
r=mid-;
}
printf("%d\n",res2-res1+);
}
else
printf("0\n");
}
} } return ;
}
/**
5 12
D 3
D 2
D 1
D 1
D 2
R
R
R
Q 1
Q 2
Q 3
Q 4
*/

hdu1540-Tunnel Warfare-(线段树+二分)的更多相关文章

  1. hdu1540 Tunnel Warfare 线段树/树状数组

    During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast a ...

  2. HDU1540 Tunnel Warfare —— 线段树 区间合并

    题目链接:https://vjudge.net/problem/HDU-1540 uring the War of Resistance Against Japan, tunnel warfare w ...

  3. HDU 1540 Tunnel Warfare (线段树)

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

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

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

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

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

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

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

  7. Tunnel Warfare 线段树 区间合并|最大最小值

    B - Tunnel WarfareHDU - 1540 这个有两种方法,一个是区间和并,这个我个人感觉异常恶心 第二种方法就是找最大最小值 kuangbin——线段树专题 H - Tunnel Wa ...

  8. HDU 1540 Tunnel Warfare (线段树)

    题目大意: n 个村庄排列在一条直线上,相邻的村庄有地道连接,除首尾两个村庄外,其余村庄都有两个相邻的村庄.其中有 3 中操作 D x :表示摧毁编号为 x 的村庄,Q x:表示求出包含村庄 x 的最 ...

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

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

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

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

随机推荐

  1. MySQL常见的应用异常记录

    >>Error Code: 1045. Access denied for user 'test'@'%' (using password: YES) 使用MySQL的select * i ...

  2. LOJ2392 JOISC2017 烟花棒 二分、贪心

    传送门 先二分一个最大速度\(v\). 分析移动的性质.很显然的事情是在火焰两边的所有人都会往火焰的方向以最快的速度运动,这样可以使当前位置更早获得火焰,同时当前拥有火焰的若干个人为了传递火焰自然也会 ...

  3. 『7.3 NOIP模拟赛题解』

    T1 gift Description ​ 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生日礼物. ​ 商店里一共有种礼物.夏川每得到一种礼物,就会获得相应喜悦值Wi(每种礼物的喜 ...

  4. C#读写调整设置UVC摄像头画面-亮度

    有时,我们需要在C#代码中对摄像头的亮度进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄像 ...

  5. .NET中的泛型概述

    什么是泛型? 泛型是具有占位符(类型参数)的类.结构.接口和方法,这些占位符是类.结构.接口和方法所存储或使用的一个或多个类型的占位符.泛型集合类可以将类型形参用作其存储的对象类型的占位符:类型形参呈 ...

  6. 让div在body中任意拖动

    HTML代码 <div id="idOuterDiv" class="CsOuterDiv"> </div> CSS代码 body { ...

  7. java 枚举示例

    public enum YNEnum { N(0,"否"), Y(1,"是"); private int code; private String name; ...

  8. springboot整合docker部署

    环境安装 首先,需要安装Docker(例如:docker for windows) 下载地址:https://download.docker.com/win/stable/Docker%20for%2 ...

  9. Socker编程之UDP

    一:socket简介 1. 不同电脑上的进程之间如何通信 首要解决的问题是如何唯一标识一个进程,否则通信无从谈起! 在1台电脑上可以通过进程号(PID)来唯一标识一个进程,但是在网络中这是行不通的. ...

  10. 【转载】C#如何往DataTable中新增一个数据列

    在C#中的Datatable数据变量的操作过程中,有时候我们需要往现有的DataTable中新增一个自定义数据列,该列在原有的DataTable变量中并不存在,属于用户手工自定义新增的数据列,在往Da ...