2019.01.19 bzoj4592: [Shoi2015]脑洞治疗仪(ODT)

版权声明:随意转载哦......但还是请注明出处吧: https://blog.csdn.net/dreaming__ldx/article/details/86552058

传送门
ODT水题。
支持区间01赋值,区间填补(把区间 [ l , r ] [l,r] 从左往右数 k k 个1都变成0),区间查询最长连续1个数。


思路:
区间填补操作感觉不是很好弄,写线段树的神仙可以套一个二分来写。
而对于写 o d t odt 的朋友们来说就很 e a s y easy 了,直接从左往右遍历到第 k k 个1所在区间覆盖一波即可(详见代码)。
不会 O D T ODT 的点这里
代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans;
}
struct Node{
    int l,r;
    mutable int v;
    Node(int l,int r=-1,int v=0):l(l),r(r),v(v){}
    friend inline bool operator<(const Node&a,const Node&b){return a.l<b.l;}
};
set<Node>S;
typedef set<Node>::iterator It;
inline It split(int pos){
    It it=S.lower_bound(pos);
    if(it!=S.end()&&it->l==pos)return it;
    --it;
    if(pos>it->r)return S.end();
    int l=it->l,r=it->r,v=it->v;
    return S.erase(it),S.insert(Node(l,pos-1,v)),S.insert(Node(pos,r,v)).first;
}
inline void assign(int l,int r,int v){
    It R=split(r+1),L=split(l);
    S.erase(L,R),S.insert(Node(l,r,v));
}
inline int query(int l,int r){
    It R=split(r+1),L=split(l);
    int ret=0,sum=0;
    for(It it=L;it!=R;++it)sum=it->v?(sum+it->r-it->l+1):0,ret=max(ret,sum);
    return ret;
}
inline int qsum(int l,int r){
    It R=split(r+1),L=split(l);
    int ret=0;
    for(It it=L;it!=R;++it)ret+=(1-it->v)*(it->r-it->l+1);
    return S.erase(L,R),S.insert(Node(l,r,1)),ret;
}
inline void update(int l,int r,int k){
    if(!k)return;
    if(k>=r-l+1){assign(l,r,0);return;}
    It it,R=split(r+1),L=split(l);
    for(It it=L;it!=R&&k;++it){
        if(it->v){
            k-=it->r-it->l+1;
            if(k<0){assign(it->l,it->r+k,0);return;}
            else it->v=0;
        }
    }
}
int main(){
    S.insert(Node(1,read(),0));
    for(ri op,l,r,x,y,v,tt=read();tt;--tt){
        op=read(),l=read(),r=read();
        switch(op){
            case 0:assign(l,r,1);break;
            case 1:{
                x=read(),y=read(),update(x,y,qsum(l,r));
                break;
            }
            default:cout<<query(l,r)<<'\n';
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dreaming__ldx/article/details/86552058