hdu 1540 Tunnel Warfare

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

Tunnel Warfare(区间合并更新)

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


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
 
题意:在抗日战争期间,地道战在华北平原得到广泛的实施,一般而言,村庄通过一些隧道在一条线上连接,除了两端剩下的每个村庄都有两个相连。
侵略者会频繁的对这些村庄进行扫荡,并且摧他们的地道,当然八路军会把这一些已经被摧毁的村庄修复的,会优先修复最近被破坏的村庄。
D表示破坏某个村庄
R表示修建某个村庄
Q表示询问
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <stack>

using namespace std;

#define N 150600
#define met(a, b) memset (a, b, sizeof (a))

typedef long long LL;
//const int INF = ((1<<31)-1);

struct node
{
    int l, r, mid, len, lsum, rsum, sum, Lson, Rson;

    void Init (int rt, int L, int R)
    {
        l = L, r = R;
        mid = (L+R) / 2;
        len = R-L+1;
        Lson = rt<<1;
        Rson = rt<<1|1;
    }
}tree[N*4];

void build (int rt, int l, int r)
{
    tree[rt].Init(rt, l, r);
    tree[rt].sum = tree[rt].lsum = tree[rt].rsum = tree[rt].len;

    if (l == r) return;

    build (tree[rt].Lson, l, tree[rt].mid);
    build (tree[rt].Rson, tree[rt].mid+1, r);
}

void update (int rt)
{
    tree[rt].lsum = tree[rt<<1].lsum;
    tree[rt].rsum = tree[rt<<1|1].rsum;

    if (tree[rt<<1].lsum == tree[rt<<1].len)
        tree[rt].lsum = tree[rt<<1].lsum + tree[rt<<1|1].lsum;
    if (tree[rt<<1|1].rsum == tree[rt<<1|1].len)
        tree[rt].rsum = tree[rt<<1|1].rsum + tree[rt<<1].rsum;

    tree[rt].sum = max (tree[rt].lsum, tree[rt].rsum);
}

void down (int rt, int k, int e)
{
    if (tree[rt].l == tree[rt].r)
    {
        tree[rt].sum = tree[rt].lsum = tree[rt].rsum = e;
        return;
    }

    if (k <= tree[rt].mid) down (tree[rt].Lson, k, e);
    else down (tree[rt].Rson, k, e);

    update (rt);
}

int query (int rt, int k)
{
    if (!tree[rt].sum) return 0;

    if (k < tree[rt<<1].l + tree[rt].lsum) return tree[rt].lsum;//判断是否在左边
    if (k > tree[rt<<1|1].r - tree[rt<<1|1].rsum) return tree[rt].rsum;//判断是否在右边
    if (k<tree[rt<<1|1].l+tree[rt<<1|1].lsum && k>tree[rt<<1].r-tree[rt<<1].rsum)
        return tree[rt<<1|1].lsum+tree[rt<<1].rsum;

    if (k <= tree[rt].mid) return query (tree[rt].Lson, k);
    else return query (tree[rt].Rson, k);
}

int main ()
{
    int n, m;
    while (scanf ("%d %d", &n, &m) != EOF)
    {
        stack <int> sta;
        build (1, 1, n);

        while (m--)
        {
            char s[10];
            int x;

            scanf ("%s", s);

            if (s[0] == 'D')
            {
                scanf ("%d", &x);
                down (1, x, 0);
                sta.push (x);
            }
            else if (s[0] == 'R')
            {
                down (1, sta.top(), 1);
                sta.pop();
            }
            else
            {
                scanf ("%d", &x);
                printf ("%d\n", query (1, x));
            }
        }
    }
    return 0;
}


你可能感兴趣的:(hdu 1540 Tunnel Warfare)