• 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
  • 相关阅读:
    【转】HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap区别
    【转】ArrayList循环遍历并删除元素的常见陷阱
    【转】Java内存管理:深入Java内存区域
    【转】java-String中的 intern()
    Jenkins + Ant + Git + Tomcat自动化部署
    Java的四种内部类
    java中的匿名内部类总结
    【转】如何提高意志力&如何坚持每天学习
    【转】前端工程筹建NodeJs+gulp+bower
    转 旧衣服不要扔,竟然还能这样改造,美翻了!
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9887298.html
Copyright © 2020-2023  润新知