poj 2892

Tunnel Warfare

Time Limit: 1000MS   Memory Limit: 131072K
Total Submissions: 6972   Accepted: 2864

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 (nm ≤ 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:

  1. D x: The x-th village was destroyed.
  2. Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself.
  3. 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

Hint

An illustration of the sample input:

      OOOOOOO

D 3   OOXOOOO

D 6   OOXOOXO

D 5   OOXOXXO

R     OOXOOXO

R     OOXOOOO

Source

POJ Monthly--2006.07.30, updog

AC代码:

#include<algorithm>
#include<iostream>
#include<stdio.h>
#include<stack>
#include<cstring>
using namespace std;
int n,m;
int c[50005],d[50005];
stack <int> st;
int lowbit(int x){
    return x&-x;
}
int sum(int x){
    int ret=0;
    while(x>=1){
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
void add(int x,int val){
    while(x<=n){
        c[x]+=val;
        x+=lowbit(x);
    }
}
int sol(int x){
    int left,right,mid;
    int ans=n+1;
    left=0; right=n+1;        //注意这里的ans,left和right的初始值
    while(left<=right){
        mid=(left+right)>>1;
        if(sum(mid)>=x){
            ans=mid;
            right=mid-1;
        }
        else
            left=mid+1;
    }
    return ans;
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(c,0,sizeof(c));
        memset(d,0,sizeof(d));
        while(!st.empty())
            st.pop();
        while(m--){
            char s[2];
            scanf("%s",s);
            if(s[0]=='D'){
                int x; scanf("%d",&x);
                if(d[x]){
                    continue;
                }
                else{
                    st.push(x);
                    d[x]=1;
                    add(x,1);
                }
            }
            else if(s[0]=='Q'){
                int x; scanf("%d",&x);
                if(d[x]){
                    printf("0\n");
                }
                else{
                    int sm=sum(x);
                    int left,right;
                    left=sol(sm);
                    right=sol(sm+1);
                    //printf("%d %d\n",left,right);
                    printf("%d\n",right-left-1);
                }
            }
            else{
                if(st.empty()){
                    continue;
                }
                else{
                    d[st.top()]=0;
                    add(st.top(),-1);
                    st.pop();
                }
            }
        }
    }
    return 0;
}

时间: 2024-10-15 09:39:11

poj 2892的相关文章

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

POJ 2892 Tunnel Warfare (树状数组+二分)

题目大意: 三个操作 D pos  将pos位置摧毁,让它和周围不相连. Q pos 问和pos 相连的有多少个村庄. R 修复最近摧毁的村庄. 思路分析: 树状数组记录这个区间有多少个1. 如果  [s-e] 有e-s+1个1 的话.那么这个区间是相连的. 这样的话,我们就可以用二分的办法求出与某个位置最大相连的数量. 还有这里二分 while(l<=r) { if(满足) { ans=mid; l=mid+1; } else r=mid-1; } #include <cstdio>

POJ 2892 Tunnel Warfare [树状数组]

题目链接: http://poj.org/problem?id=2892 题意:一个长度为n的线段,下面m个操作 D x 表示将单元x毁掉 R  表示修复最后毁坏的那个单元 Q x  询问这个单元以及它周围有多少个连续的单元,如果它本身已经被毁坏了就是0 思路: 这道题是经典的线段树入门题目,由于只是进行单点更新, 不涉及区间更新,用树状数组更简洁. 维护两个树状数组,一个是把所有的1进行维护,一个是把所有的0进行维护. 翻转(炸毁或修复)任何一个单元,同时修改这两个树状数组,仅仅是为了 合并 

【poj 2892】Tunnel Warfare 二分+树状数组

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

poj 2892 stl或线段树

标准解法应该是线段树,这里提供另一种思路:将“断点”(即被摧毁的村庄)放入stl的容器(我用的是set)中维护,对于每次查询,只要找这个数在哪两个断点之间即可,写起来轻松愉快. PS:hdu上的数据略坑,同一个村庄可以被摧毁多次,恢复的时候一次恢复就可以让它不再是断点,但是第一次恢复以后剩下几次也是需要恢复的...所以不能把它被摧毁的记录删除,另外没有被摧毁的村庄时也有R操作.poj上的数据比较规范,符合实际情况,没有上面的奇怪数据. 1 #include <algorithm> 2 #inc

poj 2892(二分+树状数组)

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

HDU 1540 POJ 2892 Tunnel Warfare

线段树 区间合并 单点修改 区间查询.又是1秒钟构思,差错查了好久... ... 发现一个int型的定义成了char型,打脸. #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set&