20分求助
查看原帖
20分求助
406832
MikefengCrzyThsday楼主2022/6/22 13:48
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2e5+5;
int n,m;
struct node{
	int lmax,rmax,maxn,tag,sum,len;
}tree[N<<2];
void pushdown(int k){
	if(tree[k].tag==1){
		tree[k*2].lmax=tree[k*2].rmax=tree[k*2].maxn=tree[k*2].len;
		tree[k*2].sum=0;
		tree[k*2].tag=1;
		tree[k*2+1].lmax=tree[k*2+1].rmax=tree[k*2+1].maxn=tree[k*2+1].len;
		tree[k*2+1].sum=0;
		tree[k*2+1].tag=1;
		tree[k].tag=0;
	}else if(tree[k].tag==2){
		tree[k*2].lmax=tree[k*2].rmax=tree[k*2].maxn=0;
		tree[k*2].sum=tree[k*2].len;
		tree[k*2].tag=2;
		tree[k*2+1].lmax=tree[k*2+1].rmax=tree[k*2+1].maxn=0;
		tree[k*2+1].sum=tree[k*2+1].len;
		tree[k*2+1].tag=2;
		tree[k].tag=0;
	}
}
void pushup(int k){
	if(tree[k*2].lmax==tree[k*2].len) tree[k].lmax=tree[k*2].len+tree[k*2+1].lmax;
	else tree[k].lmax=tree[k*2].lmax;
	if(tree[k*2+1].rmax==tree[k*2+1].len) tree[k].rmax=tree[k*2+1].len+tree[k*2].rmax;
	else tree[k].rmax=tree[k*2+1].rmax;
	tree[k].maxn=max(tree[k*2].rmax+tree[k*2+1].lmax,max(tree[k*2].maxn,tree[k*2+1].maxn));
	tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
}
void build(int k,int l,int r){
	tree[k].len=r-l+1;
	if(l==r){
		tree[k].lmax=tree[k].rmax=tree[k].maxn=0;
		tree[k].sum=1;
		return;
	}
	int mid=(l+r)>>1;
	build(k*2,l,mid);
	build(k*2+1,mid+1,r);
	pushup(k);
}
void change(int k,int l,int r,int l1,int r1,int val){
	if(l1<=l&&r<=r1){
		tree[k].sum=tree[k].len*val;
		tree[k].lmax=tree[k].rmax=tree[k].maxn=tree[k].len-tree[k].sum;
		tree[k].tag=val+1;
		return;
	}
	pushdown(k);
	int mid=(l+r)>>1;
	if(l1<=mid) change(k*2,l,mid,l1,r1,val);
	if(mid<r1) change(k*2+1,mid+1,r,l1,r1,val);
	pushup(k);
}
int query(int k,int l,int r,int l1,int r1){
	if(l1<=l&&r<=r1) return tree[k].maxn;
	pushdown(k);
	int mid=(l+r)>>1,ans;
	if(l1<=mid&&mid<r1) ans=max(max(query(k*2,l,mid,l1,r1),query(k*2+1,mid+1,r,l1,r1)),min(tree[k*2].rmax,mid+1-l1)+min(tree[k*2+1].lmax,r1-mid));
	else if(l1<=mid) ans=query(k*2,l,mid,l1,r1);
	else ans=query(k*2+1,mid+1,r,l1,r1);
	return ans;
}
int query1(int k,int l,int r,int l1,int r1){
	if(l1<=l&&r<=r1) return tree[k].sum;
	pushdown(k);
	int mid=(l+r)>>1,ans=0;
	if(l1<=mid) ans+=query(k*2,l,mid,l1,r1);
	if(mid<r1) ans+=query(k*2+1,mid+1,r,l1,r1);
	return ans;
}
void add(int l,int r,int l1,int r1){
	int num=r-l+1-query1(1,1,n,l,r);
	if(!num) return;
	change(1,1,n,l,r,0);
	int l0=l1,r0=r1,ans;
	while(l0<=r0){
		int mid=(l0+r0)>>1;
		if(query1(1,1,n,l1,mid)<=num){
			l0=mid+1;
			ans=mid;
		}else r0=mid-1;
	}
	change(1,1,n,l1,ans,1);
}
int read(){
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-48;
		c=getchar();
	}
	return x*f;
}
int main(){
	n=read();m=read();
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt,l,r,l1,r1;
		opt=read();
		if(opt==0){
			l=read();r=read();
			change(1,1,n,l,r,0);
		}else if(opt==1){
			l=read();r=read();l1=read();r1=read();
			add(l,r,l1,r1);
		}else{
			l=read();r=read();
			printf("%d\n",query(1,1,n,l,r));
		}
	}
	return 0;
}
2022/6/22 13:48
加载中...