hdu1540-Tunnel Warfare-(线段树+二分)
题意:有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-(线段树+二分)的更多相关文章
- hdu1540 Tunnel Warfare 线段树/树状数组
During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast a ...
- HDU1540 Tunnel Warfare —— 线段树 区间合并
题目链接:https://vjudge.net/problem/HDU-1540 uring the War of Resistance Against Japan, tunnel warfare w ...
- HDU 1540 Tunnel Warfare (线段树)
Tunnel Warfare Problem Description During the War of Resistance Against Japan, tunnel warfare was ca ...
- 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 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...
- Tunnel Warfare 线段树 区间合并|最大最小值
B - Tunnel WarfareHDU - 1540 这个有两种方法,一个是区间和并,这个我个人感觉异常恶心 第二种方法就是找最大最小值 kuangbin——线段树专题 H - Tunnel Wa ...
- HDU 1540 Tunnel Warfare (线段树)
题目大意: n 个村庄排列在一条直线上,相邻的村庄有地道连接,除首尾两个村庄外,其余村庄都有两个相邻的村庄.其中有 3 中操作 D x :表示摧毁编号为 x 的村庄,Q x:表示求出包含村庄 x 的最 ...
- 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. ...
随机推荐
- docker compose 编排
Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景. 说明:Comp ...
- C++随机数笔记
版权声明:本文为CSDN博主「candyliuxj」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/can ...
- Java学习: 面向对象的使用与注意事项
面向对象的使用与注意事项 面向过程:当需要实现一个功能的时候,每一个具体的步骤都需要亲力,详细处理每一个细节面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做 ...
- 前端不缓存,ajax不缓存,js操作cookie
今天实现网站注销功能时,需要清除cookie缓存,开始在网上搜索的是“js清除缓存”,发现很多都是预先防患缓存存储的内容,千篇一律,不过也学习到了:后来换成"js清除cookie" ...
- Django--一对多表操作
目录 Django--一对多表操作 需求 步骤 添加路由映射关系 学生表的增删改查 ajax更新和添加 Django--一对多表操作 今天还以一个学生管理系统为例,先通过pymysql这个模块,进行一 ...
- vue中对象数组去重
其实很简单,一般的数组去重可以直接用 new Set() 方法即可,但是数组对象的话,比较复杂,不能直接用,我们可以采取间接的方法来去重 unique(arr) { const res = new M ...
- JavaScript 之 history对象
location.history 对象是浏览器的一个历史对象,可以用来前进和后退. 1.back() 方法 history.back(); 浏览器的历史记录会记录原来的地址,这个方法将会返回到上一页. ...
- android中listview滑动卡顿的原因
导致Android界面滑动卡顿主要有两个原因: 1.UI线程(main)有耗时操作 2.视图渲染时间过长,导致卡顿 http://www.tuicool.com/articles/fm2IFfU
- python可视化_matplotlib
对于Python数据可视化库,matplotlib 已经成为事实上的数据可视化方面最主要的库,此外还有很多其他库,例如vispy,bokeh, seaborn,pyga,folium 和 networ ...
- C语言深入学习
计算机存储篇 1.计算机对数据类型的辨别: 编译器在编译C程序时将其转变为汇编指令,其中指明了数据类型.此外,每种数据类型都有固定的存储长度,计算机运行程序时,会根据具体类型 读出相应长度的数据进行计 ...