给你一个序列,一开始都是 $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)); } } }