zoukankan      html  css  js  c++  java
  • SHOI2015 脑洞治疗仪

    给你一个序列,一开始都是 $1$,资瓷 $3$ 种操作

    1.把 $[l,r]$ 赋值为 $0$

    2.把 $[l,r]$ 中所有 $1$ 删掉,记录删掉的 $1$ 的个数,并把这些 $1$ 从左到右填到 $[a,b]$ 中的 $0$ 处,不考虑 $1$ 的剩余(剩下的相当于全扔了)

    3.查询 $[l,r]$ 中最长连续的 $0$ 的个数

    sol:

    好像会珂朵莉树这题就是模拟啊...应该是当年 SHOI 的人不知道有这种黑珂技

    感觉跑的比线段树快呀。。。

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
        for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
        return x * f;
    }
    struct node
    {
        int l,r;
        mutable bool v;
        node(int L,int R = -1,bool vv = 0):l(L),r(R),v(vv){}
        bool operator < (const node &b)const{return l < b.l;}
    };
    set<node> s;
    int n,m;
    inline set<node>::iterator split(int pos)
    {
        auto it = s.lower_bound(node(pos));
        if(it != s.end() && it -> l == pos)return it;
        --it;int L = it -> l,R = it -> r,vv = it -> v;
        s.erase(it);s.insert(node(L,pos - 1,vv));
        return s.insert(node(pos,R,vv)).first;
    }
    inline void Rua(int l,int r,int v)
    {
        auto itr = split(r + 1),itl = split(l);
        s.erase(itl,itr);
        s.insert(node(l,r,v));
    }
    inline void heal(int l,int r,int a,int b)
    {
        auto itr = split(r + 1),itl = split(l),nowit = itl;
        int sum = 0;
        for(;itl != itr;++itl)
            if(itl -> v)
                sum += (itl -> r - itl -> l + 1);
        s.erase(nowit,itr);
        s.insert(node(l,r,0));
        if(!sum)return;
        itr = split(b + 1),itl = split(a),nowit = itl;
        if(sum >= b - a + 1)
        {
            s.erase(nowit,itr);
            s.insert(node(a,b,1));
            return;
        }
        for(;itl != itr;++itl)
            if(!itl -> v)
            {
                sum -= (itl -> r - itl -> l + 1);
                if(sum < 0)
                {
                    Rua(itl -> l,itl -> r + sum,1);
                    return;
                }
                else itl -> v = 1;
            }
    }
    inline int query(int l,int r)
    {
        auto itr = split(r + 1),itl = split(l),nowit = itl;
        int mx = 0,now = 0;
        for(;itl != itr;++itl)
            if(!itl -> v)
                now += (itl -> r - itl -> l + 1);
            else if(now != 0)mx = max(mx,now),now = 0;
        return max(mx,now);
    }
    int main()
    {
        n = read(),m = read();s.insert(node(1,n,1));
        while(m--)
        {
            int opt = read(),l = read(),r = read();
            if(!opt)Rua(l,r,0);
            else if(opt == 1)
            {
                int a = read(),b = read();
                heal(l,r,a,b);
            }
            else
            {
                printf("%d
    ",query(l,r));
            }
        }
    }
    View Code
  • 相关阅读:
    【crontab】误删crontab及其恢复
    New Concept English there (7)
    New Concept English there (6)
    New Concept English there (5)
    New Concept English there (4)
    New Concept English there (3)
    New Concept English there (2)Typing speed exercise
    New Concept English there (1)Typing speed exercise
    New Concept English Two 34 game over
    New Concept English Two 33 94
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9887298.html
Copyright © 2011-2022 走看看