博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu 1540 Tunnel Warfare(线段树区间统计)
阅读量:6815 次
发布时间:2019-06-26

本文共 3305 字,大约阅读时间需要 11 分钟。

Tunnel Warfare

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 3293    Accepted Submission(s): 1272

Problem Description
During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally speaking, villages connected by tunnels lay in a line. Except the two at the ends, every village was directly connected with two neighboring ones.
Frequently the invaders launched attack on some of the villages and destroyed the parts of tunnels in them. The Eighth Route Army commanders requested the latest connection state of the tunnels and villages. If some villages are severely isolated, restoration of connection must be done immediately!
 

 

Input
The first line of the input contains two positive integers n and m (n, m ≤ 50,000) indicating the number of villages and events. Each of the next m lines describes an event.
There are three different events described in different format shown below:
D x: The x-th village was destroyed.
Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself.
R: The village destroyed last was rebuilt.
 

 

Output
Output the answer to each of the Army commanders’ request in order on a separate line.
 

 

Sample Input
7 9 D 3 D 6 D 5 Q 4 Q 5 R Q 4 R Q 4
 

 

Sample Output
1 0 2 4
 

 

Source
 

 

Recommend
LL
 
题意:
是一条线上的点,D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点。
思路:
这是一道典型的线段树区间统计类题目。用线段树维护两个值ml,mr。ml表示结点对应区间左连续点(即连通村子)的个数。mr区间右连续点的个数。对于D和R操作都很简单。单点修改递归更新就行了。对于R操作用一个栈记录摧毁村子的标号就行。有点难的是询问操作。就是询问一个点所在连续区间元素的个数。
一个点对应于线段树区间只有3种情况。
1.在左连续区间内。
2.在右连续区间内。
3.夹在这两个区间内。
分情况处理就好。
只是要注意。这题有点坑。discuss里面说
1)多case(2)某个村庄可以被毁坏多次(必须全部入栈),但只需要一次就能将其恢复(下面的这组数据,,)(3)D 3  D 2  D 1  D 1  D 2    R  恢复2    R  恢复1    R  恢复3
其实根本不用。这么做反而wa了。不用考虑那么多D就直接入栈。R就直接出栈就行了。
详细见代码:
#include 
#include
#include
using namespace std;const int maxn=50010;int ml[maxn<<2],mr[maxn<<2],sta[maxn];//sta为栈int flag,tail;void btree(int L,int R,int k){ int ls,rs,mid; ml[k]=mr[k]=R-L+1; if(L==R) return; ls=k<<1; rs=ls|1; mid=(L+R)>>1; btree(L,mid,ls); btree(mid+1,R,rs);}void update(int L,int R,int k,int p,int op)//更新很简单{ int ls,rs,mid; if(L==R) { if(op) ml[k]=mr[k]=0; else ml[k]=mr[k]=1; return; } ls=k<<1; rs=ls|1; mid=(L+R)>>1; if(p>mid) update(mid+1,R,rs,p,op); else update(L,mid,ls,p,op); ml[k]=ml[ls]; mr[k]=mr[rs]; if(ml[ls]==mid-L+1) ml[k]+=ml[rs]; if(mr[rs]==R-mid) mr[k]+=mr[ls];}int qu(int L,int R,int k,int p){ int ls,rs,mid,t; if(mr[k]>=R-p+1) { flag=1;//加以标记。返回上层时加上扩展值 return mr[k]; } if(ml[k]>=p-L+1) { flag=1; return ml[k]; } if(L==R) return 0; ls=k<<1; rs=ls|1; mid=(L+R)>>1; if(p>mid) { t=qu(mid+1,R,rs,p); if(flag) { flag=0; t+=mr[ls]; } } else { t=qu(L,mid,ls,p); if(flag) { flag=0; t+=ml[rs]; } } return t;}int main(){ int n,m,p,i; char com[10]; while(~scanf("%d%d",&n,&m)) { btree(1,n,1); flag=tail=0; for(i=0;i

转载地址:http://efdzl.baihongyu.com/

你可能感兴趣的文章
Android studio 快捷键
查看>>
python小程序 批量提交bugscan
查看>>
结缘PDO
查看>>
学习微信小程序之css18绝对定位
查看>>
关于Override在JDK1.5和JDK1.6上子类实现接口中方法使用@Override注解编译错误.
查看>>
canvas 的学习
查看>>
oj2694 逆波兰表达式
查看>>
页面css代码
查看>>
Google Map API使用详解(九)——Google Map坐标系统总结(下)
查看>>
SQL Server返回插入数据的ID和受影响的行数
查看>>
APP测试常见点
查看>>
JavaScript+HTML5 实现打地鼠小游戏
查看>>
转一下递归
查看>>
浅谈利用同步机制解决Java中的线程安全问题
查看>>
第三章 列表简介
查看>>
四则运算设计思路
查看>>
每间隔15分钟生成一个时间戳
查看>>
【学习】python(os)模块总结
查看>>
JAVA毕业后工资有多少?
查看>>
android,HttpPost 提交数据
查看>>