码迷,mamicode.com
首页 > 其他好文 > 详细

SHOI2015 脑洞治疗仪

时间:2018-11-01 12:00:30      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:define   分享   none   const   def   getc   ons   模拟   oid   

给你一个序列,一开始都是 $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\n",query(l,r));
        }
    }
}
View Code

 

SHOI2015 脑洞治疗仪

标签:define   分享   none   const   def   getc   ons   模拟   oid   

原文地址:https://www.cnblogs.com/Kong-Ruo/p/9887298.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!