• 【LOJ】#2037. 「SHOI2015」脑洞治疗仪


    题解

    维护区间内1的个数,左边数0的长度,右边数0的长度,区间内0区间最长个数,覆盖标记
    第一种操作区间覆盖0
    第二种操作查询([l_0,r_0])中1的个数,区间覆盖0,然后覆盖时找到相对应的区间时对于如果1够把这个区间覆盖掉的话就直接cover,否则就递归该区间,如果能覆盖左区间就覆盖去右区间否则就覆盖左区间
    第三种操作直接查询左右区间特判跨越中间

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define MAXN 200005
    #define pb push_back
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 + c - '0';
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int N,M;
    struct node {
        int l,r,ll,rl,cov,cnt,v;
    }tr[MAXN * 4];
    void cover(int u,int v) {
        int len = tr[u].r - tr[u].l + 1;
        tr[u].cov = v;
        if(!v) {tr[u].ll = len;tr[u].rl = len;tr[u].v = len;tr[u].cnt = 0;}
        else {tr[u].ll = 0;tr[u].rl = 0;tr[u].v = 0;tr[u].cnt = len;}
    }
    void update(int u) {
        tr[u].v = max(tr[u << 1].v,tr[u << 1 | 1].v);
        tr[u].v = max(tr[u << 1].rl + tr[u << 1 | 1].ll,tr[u].v);
        tr[u].cnt = tr[u << 1].cnt + tr[u << 1 | 1].cnt;
        tr[u].ll = (!tr[u << 1].cnt) ? tr[u << 1].r - tr[u << 1].l + 1 + tr[u << 1 | 1].ll : tr[u << 1].ll;
        tr[u].rl = (!tr[u << 1 | 1].cnt) ? tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1 + tr[u << 1].rl : tr[u << 1 | 1].rl;
    }
    void push_down(int u) {
        if(tr[u].cov != -1) {
            cover(u << 1,tr[u].cov);
            cover(u << 1 | 1,tr[u].cov);
            tr[u].cov = -1;
        }
    }
    void build(int u,int l,int r) {
        tr[u].l = l;tr[u].r = r;tr[u].cov = -1;
        if(l == r) {
            cover(u,1);
            return;
        }
        int mid = (l + r) >> 1;
        build(u << 1,l,mid);
        build(u << 1 | 1,mid + 1,r);
        update(u);
    }
    
    int cmp(int a,int b,int on) {
        if(!on) return a + b;
        else return max(a,b);
    }
    int Query(int u,int l,int r,int on) {
        if(tr[u].l == l && tr[u].r == r) {
            if(!on) return tr[u].cnt;
            else return tr[u].v;
        }
        push_down(u);
        int mid = (tr[u].l + tr[u].r) >> 1;
        if(r <= mid) return Query(u << 1,l,r,on);
        else if(l > mid) return Query(u << 1 | 1,l,r,on);
        else {
            int x = cmp(Query(u << 1,l,mid,on),Query(u << 1 | 1,mid + 1,r,on),on);
            if(on) {
                int pl = max(l,tr[u << 1].r - tr[u << 1].rl + 1),pr = min(r,tr[u << 1 | 1].l + tr[u << 1 | 1].ll - 1);
                x = max(x,pr - pl + 1);
            }
            return x;
        }
    }
    void Cover(int u,int l,int r,int v) {
        if(tr[u].l == l && tr[u].r == r) {cover(u,v);return;}
        push_down(u);
        int mid = (tr[u].l + tr[u].r) >> 1;
        if(r <= mid) Cover(u << 1,l,r,v);
        else if(l > mid) Cover(u << 1 | 1,l,r,v);
        else {Cover(u << 1,l,mid,v);Cover(u << 1 | 1,mid + 1,r,v);}
        update(u);
    }
    void repair(int u,int cnt) {
        if(!cnt) return;
        if(tr[u].l == tr[u].r) {cover(u,1);return;}
        push_down(u);
        if(tr[u << 1].r - tr[u << 1].l + 1 - tr[u << 1].cnt <= cnt) {
            cnt -= tr[u << 1].r - tr[u << 1].l + 1 - tr[u << 1].cnt;cover(u << 1,1);
            repair(u << 1 | 1,cnt);
        }
        else repair(u << 1,cnt);
        update(u);
    }
    int C;
    void Repair(int u,int l,int r) {
        if(!C) return;
        if(tr[u].l == l && tr[u].r == r) {
            if(C >= r - l + 1 - tr[u].cnt) {
                C -= r - l + 1 - tr[u].cnt;
                cover(u,1);
            }
            else {repair(u,C);C = 0;}
            return;
        }
        int mid = (tr[u].l + tr[u].r) >> 1;
        push_down(u);
        if(r <= mid) Repair(u << 1,l,r);
        else if(l > mid) Repair(u << 1 | 1,l,r);
        else {Repair(u << 1,l,mid);Repair(u << 1 | 1,mid + 1,r);}
        update(u);
    }
    void Solve() {
        read(N);read(M);
        build(1,1,N);
        int op,l0,r0,l1,r1;
        for(int i = 1 ; i <= M ; ++i) {
            read(op);read(l0);read(r0);
            if(op == 1) {read(l1);read(r1);}
            if(op == 0) {
                Cover(1,l0,r0,0);
            }
            else if(op == 1) {
                C = Query(1,l0,r0,0);
                Cover(1,l0,r0,0);
                Repair(1,l1,r1);
            }
            else {
                out(Query(1,l0,r0,1));enter;
            }
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
        return 0;
    }
    

    水题,但是我忘pushdown了,WA了一次,代码能力--

  • 相关阅读:
    redhat Nginx 安装
    黑客经验谈:跳板攻击入侵技术实例解析
    Linux各版本的本地root密码破解方法
    python学习笔记
    Git 提交的正确姿势:Commit message 编写指南
    数论 + 扩展欧几里得
    数论
    flutter 延时函数delay Loading页面
    flutter 切换tab后保留tab状态
    iOS 应用"无法安装应用程序 因为证书无效"的解决方案
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9489783.html
Copyright © 2020-2023  润新知