Tunnel Warfare HDU - 1540 (线段树,区间合并)

题意:有n座房子,起初都是完好的,有m次操作,可以销毁i号房屋,可以重建最后一个销毁的房屋,可以查询i号房屋和几个房屋直接或间接相连。

题解:假设 1 2 3 4 5 6 7 8 中3 和7 已经摧毁,现在查询5,那么就是1 - 5中最靠右的毁坏的是3,5 - 8 中最靠左毁坏的的是7,那么答案就是7 - 3 - 1 = 3,当然如果刚好查询的那个已经摧毁那么就不用- 1了,所以需要维护每一个结点的最靠近它的两个左右摧毁点

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#include<cstdlib>
#include<queue>
#include<set>
#include<vector>

using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-10
typedef long long LL;
const int MAXN = 5e4 + 5;
const int mod = 998244353;

int stl[MAXN << 2],str[MAXN << 2];
int n;

void pushup(int o) {
    stl[o] = max(stl[o << 1], stl[o << 1 | 1]);
    str[o] = min(str[o << 1], str[o << 1 | 1]);
}
void build(int o,int l,int r) {
    if (l == r) {
        stl[o] = 0;
        str[o] = n + 1;
    } else {
        int mid = (l + r) >> 1;
        build(o << 1, l, mid);
        build(o << 1 | 1, mid + 1, r);
        pushup(o);
    }
}
void update(int o,int l,int r,int pos,int id) {// id用来判断是破坏还是修复
    if (l == r) {
        if (id)
        {
            stl[o] = max(stl[o],id);
            str[o] = min(str[o],id);
        }
        else {
            stl[o] = 0;
            str[o] = n + 1;
        }
    } else {
        int mid = (l + r) >> 1;
        if (pos <= mid) update(o << 1, l, mid, pos, id);
        else update(o << 1 | 1, mid + 1, r, pos, id);
        pushup(o);
    }
}
int query_r(int o,int l,int r,int ql,int qr) {
    if(ql <= l && r <= qr) return str[o];
    int mid = (l + r) >> 1;
    int ans = n + 1;
    if(ql <= mid) ans = min(ans,query_r(o << 1,l,mid,ql,qr));
    if(qr > mid) ans = min(ans,query_r(o << 1 | 1,mid + 1,r,ql,qr));
    return ans;
}
int query_l(int o,int l,int r,int ql,int qr) {
    if(ql <= l && r <= qr) return stl[o];
    int mid = (l + r) >> 1;
    int ans = 0;
    if(ql <= mid) ans = max(ans,query_l(o << 1,l,mid,ql,qr));
    if(qr > mid) ans = max(ans,query_l(o << 1 | 1,mid + 1,r,ql,qr));
    return ans;
}

int main() {
    int m;
    while (~scanf("%d %d", &n, &m)) {
        build(1, 1, n);
        char s[5];
        int c;
        stack<int> sta;
        while (m--) {
            scanf("%s", s);
            if (s[0] == 'D') {
                scanf("%d", &c);
                update(1, 1, n, c, c);
                sta.push(c);
            }
            else if(s[0] == 'R') {
                c = sta.top();
                sta.pop();
                update(1,1,n,c,0);
            }
            else {
                scanf("%d",&c);
                int ans = query_r(1,1,n,c,n) - query_l(1,1,n,1,c) - 1;
                //printf("%d %d", query_r(1,1,n,c,n) , query_l(1,1,n,1,c));

                printf("%d\n",max(0,ans));
            }
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/smallhester/p/11330158.html