Tunnel Warfare (区间合并&最大值最小值巧妙方法)

Tunnel Warfare

http://acm.hdu.edu.cn/showproblem.php?pid=1540

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 13440    Accepted Submission(s): 5333

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

POJ Monthly

注意是多组数据。

这是用最大值最小值单点更新的方法,参考大佬的博客 https://blog.csdn.net/chudongfang2015/article/details/52133243

一开始设所有村庄最大值为0,最小值为n+1.

当村庄被摧毁时,它的最大值和最小值设为改村庄的编号,这样我们从左边区间查询最大值max,右边区间查询最小值min

当min==max时,就是该点被摧毁了,否则区间长度就是min-max-1

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<vector>
  7 #include<string>
  8 #include<stack>
  9 #define maxn 50005
 10 #define lson l,mid,rt<<1
 11 #define rson mid+1,r,rt<<1|1
 12 using namespace std;
 13
 14 int n,m;
 15 struct sair{
 16     int Max,Min;
 17 }tree[maxn<<3];
 18
 19 void build(int l,int r,int rt){
 20     if(l==r){
 21         tree[rt].Max=0;
 22         tree[rt].Min=n+1;
 23         return;
 24     }
 25     int mid=(l+r)/2;
 26     build(lson);
 27     build(rson);
 28     tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max);
 29     tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min);
 30
 31 }
 32
 33 void update_max(int L,int k,int l,int r,int rt){
 34     if(l==r){
 35         tree[rt].Max=k;
 36         return;
 37     }
 38     int mid=(l+r)/2;
 39     if(L<=mid) update_max(L,k,lson);
 40     else update_max(L,k,rson);
 41     tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max);
 42 }
 43
 44 void update_min(int L,int k,int l,int r,int rt){
 45     if(l==r){
 46         tree[rt].Min=k;
 47         return;
 48     }
 49     int mid=(l+r)/2;
 50     if(L<=mid) update_min(L,k,lson);
 51     else update_min(L,k,rson);
 52     tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min);
 53 }
 54
 55 int query_max(int L,int R,int l,int r,int rt){
 56     if(L<=l&&R>=r){
 57         return tree[rt].Max;
 58
 59     }
 60     int mid=(l+r)/2;
 61     int ans=0;
 62     if(L<=mid) ans=max(ans,query_max(L,R,lson));
 63     if(R>mid) ans=max(ans,query_max(L,R,rson));
 64     return ans;
 65 }
 66
 67 int query_min(int L,int R,int l,int r,int rt){
 68     if(L<=l&&R>=r){
 69         return tree[rt].Min;
 70     }
 71     int mid=(l+r)/2;
 72     int ans=0x3f3f3f3f;
 73     if(L<=mid) ans=min(ans,query_min(L,R,lson));
 74     if(R>mid) ans=min(ans,query_min(L,R,rson));
 75     return ans;
 76 }
 77
 78 int main(){
 79
 80     std::ios::sync_with_stdio(false);
 81     while(cin>>n>>m){
 82         char pos;
 83         int x;
 84         stack<int>st;
 85         build(1,n,1);
 86         for(int i=1;i<=m;i++){
 87             cin>>pos;
 88             if(pos==‘D‘){
 89                 cin>>x;
 90                 st.push(x);
 91                 update_max(x,x,1,n,1);
 92                 update_min(x,x,1,n,1);
 93             }
 94             else if(pos==‘Q‘){
 95                 cin>>x;
 96                 int L=query_min(x,n,1,n,1);
 97                 int R=query_max(1,x,1,n,1);
 98                 if(R==L) cout<<0<<endl;
 99                 else cout<<L-R-1<<endl;
100             }
101             else if(pos==‘R‘){
102                 x=st.top();
103                 st.pop();
104                 update_max(x,0,1,n,1);
105                 update_min(x,n+1,1,n,1);
106             }
107         }
108     }
109 }

区间合并 。。。。明天补。。

原文地址:https://www.cnblogs.com/Fighting-sh/p/9716233.html

时间: 2024-10-10 12:08:24

Tunnel Warfare (区间合并&最大值最小值巧妙方法)的相关文章

HDU 1540 Tunnel Warfare(区间合并)【线段树】

<题目链接> 题目大意: 题意:一个长度为n的线段,下面m个操作 D x 表示将单元x毁掉 R  表示修复最后毁坏的那个单元 Q x  询问这个单元以及它周围有多少个连续的单元,如果它本身已经被毁坏了就是0. 解题分析: 用线段树求指定点所在的最长连续区间,属于线段树区间合并类型的题,线段树的每个节点需要维护三个值,分别是对应区间的最长连续区间长度,对应区间最长连续区间前缀,对应区间最长连续后缀,然后就是在每次update之后都维护一下这三个值就行.并且注意一下query 时的操作. 1 #i

Tunnel Warfare HDU 1540 区间合并+最大最小值

Tunnel Warfare HDU 1540 区间合并+最大最小值 题意 D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 题解思路 参考的大佬博客 这里巧妙使用了最大值最小值来进行区间的查找.上一行是大佬的详细题解,真的很妙啊. 代码实现 #include<cstdio> #include<cstring> #include<algorithm> #include<stack> #define ls (rt&l

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

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 con

【HDOJ】1540 Tunnel Warfare

还不错的一道线段树区间合并.挺巧妙的用法. 1 /* 1540 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <alg

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

Tunnel Warfare Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1540 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Gene

HDU 1540 Tunnel Warfare 平衡树 / 线段树:单点更新,区间合并

Tunnel Warfare                                  Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast

HDU 1540 &amp;&amp; POJ 2892 Tunnel Warfare (线段树,区间合并).

~~~~ 第一次遇到线段树合并的题,又被律爷教做人.TAT. ~~~~ 线段树的题意都很好理解吧.. 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1540 http://poj.org/problem?id=2892 ~~~~ 我的代码:200ms #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #defin

hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】

Tunnel Warfare                                                             Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) 链接:hdu 1540        POJ 2892 Problem Description During the War of Resistance Against Japan,

POJ 2892 Tunnel Warfare(线段树单点更新区间合并)

Tunnel Warfare Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 7876   Accepted: 3259 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally sp