zoukankan      html  css  js  c++  java
  • Tunnel Warfare HDU

    题意:有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
    ",max(0,ans));
                }
            }
        }
    }
  • 相关阅读:
    【JAVA SE基础篇】49.文件字符流和字节数组流
    【JAVA SE基础篇】48.IO流四大抽象类介绍和字节流
    【JAVA SE基础篇】47.file类的方法
    【JAVA SE基础篇】46.IO流的介绍
    【HTML篇】4.HTML的内嵌标签、框架标签、表单
    【HTML篇】3.HTML的图片标签、超链接标签、表格标签
    【HTML篇】2.HTML的head标签和body标签
    【HTML篇】1.HTML的介绍、三大基石、标准文档结构
    【JAVA SE基础篇】45.迭代器、Collections工具类以及使用容器存储表格
    【JAVA SE基础篇】44.手工实现简易HashMap和HashSet
  • 原文地址:https://www.cnblogs.com/smallhester/p/11330158.html
Copyright © 2011-2022 走看看