75pts线段树求条,玄n关
查看原帖
75pts线段树求条,玄n关
923248
Lian_zy楼主2024/12/31 18:20

rt,找不出错

#include<bits/stdc++.h>
using namespace std;

const int N=3e5+10;
struct node{
	int l,r;
	int max0;
	int ml0,mr0;
	int sum0,sum1;
	int tag;
}t[N<<2];
int n,m,l,r,l0,r0,l1,r1,op,ans,cnt,mid;
void push_up(node &k,node ls,node rs){
	k.sum0=ls.sum0+rs.sum0;
	k.sum1=ls.sum1+rs.sum1;
	k.ml0=ls.ml0+(ls.ml0==ls.r-ls.l+1)*rs.ml0;
	k.mr0=rs.mr0+(rs.mr0==rs.r-rs.l+1)*ls.mr0;
	k.max0=max(ls.mr0+rs.ml0,max(ls.max0,rs.max0));
	return;
}
void push_down(int x){
	int tag=t[x].tag;
	if(tag==-1)return;
	if(tag){//覆盖为1 
		//ls
		t[x<<1].max0=0;
		t[x<<1].ml0=0;
		t[x<<1].mr0=0;
		t[x<<1].sum0=0;
		t[x<<1].sum1=t[x<<1].r-t[x<<1].l+1;
		//rs
		t[x<<1|1].max0=0;
		t[x<<1|1].ml0=0;
		t[x<<1|1].mr0=0;
		t[x<<1|1].sum0=0;
		t[x<<1|1].sum1=t[x<<1|1].r-t[x<<1|1].l+1;
	}else{
		//ls
		t[x<<1].max0=t[x<<1].r-t[x<<1].l+1;
		t[x<<1].ml0=t[x<<1].r-t[x<<1].l+1;
		t[x<<1].mr0=t[x<<1].r-t[x<<1].l+1;
		t[x<<1].sum0=t[x<<1].r-t[x<<1].l+1;
		t[x<<1].sum1=0;
		//rs
		t[x<<1|1].max0=t[x<<1|1].r-t[x<<1|1].l+1;
		t[x<<1|1].ml0=t[x<<1|1].r-t[x<<1|1].l+1;
		t[x<<1|1].mr0=t[x<<1|1].r-t[x<<1|1].l+1;
		t[x<<1|1].sum0=t[x<<1|1].r-t[x<<1|1].l+1;
		t[x<<1|1].sum1=0;
	}
	t[x<<1].tag=tag;
	t[x<<1|1].tag=tag;
	t[x].tag=-1;
	return;
}
void build(int x,int l,int r){
	t[x].l=l;
	t[x].r=r;
	t[x].tag=-1;
	if(l==r){
		t[x].sum1=1;
		return;
	}
	int mid=l+r>>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	push_up(t[x],t[x<<1],t[x<<1|1]);
	return;
}
void update(int x,int l,int r,int d){
	int L=t[x].l;
	int R=t[x].r;
	if(l<=L&&R<=r){
		t[x].tag=d;
		if(d){
			t[x].max0=0;
			t[x].ml0=0;
			t[x].mr0=0;
			t[x].sum0=0;
			t[x].sum1=t[x].r-t[x].l+1;
		}else{
			t[x].max0=t[x].r-t[x].l+1;
			t[x].ml0=t[x].r-t[x].l+1;
			t[x].mr0=t[x].r-t[x].l+1;
			t[x].sum0=t[x].r-t[x].l+1;
			t[x].sum1=0;
		}
		return;
	}
	push_down(x);
	int mid=L+R>>1;
	if(l<=mid)update(x<<1,l,r,d);
	if(r>mid)update(x<<1|1,l,r,d);
	push_up(t[x],t[x<<1],t[x<<1|1]);
	return;
}
node query(int x,int l,int r){
	int L=t[x].l;
	int R=t[x].r;
	if(l<=L&&R<=r)return t[x];
	push_down(x);
	bool hl=0,hr=0;
	int mid=L+R>>1;
	node ls,rs,ans;
	if(l<=mid){
		ls=query(x<<1,l,r);
		hl=1;
	}
	if(r>mid){
		rs=query(x<<1|1,l,r);
		hr=1;
	}
	if(hl&&hr){
		push_up(ans,ls,rs);
		return ans;
	}
	if(hl)return ls;
	return rs;
}
int main(){
    scanf("%d%d",&n,&m);
    build(1,1,n);
    while(m--){
    	scanf("%d%d%d",&op,&l0,&r0);
    	if(op==0)update(1,l0,r0,0);
    	if(op==1){
    		scanf("%d%d",&l1,&r1);
    		//取出l0到r0的所有1
			cnt=query(1,l0,r0).sum1;
			update(1,l0,r0,0);
			//二分,区间的0不能超过cnt,找到右边的这样的区间 
			ans=0;
			l=0,r=r1-l1+1;//二分区间长度 
			while(l<=r){
				mid=l+r>>1;
				if(query(1,l1,l1+mid-1).sum0<=cnt){
					ans=mid;
					l=mid+1;
				}else r=mid-1;
			}
			//获得区间大小ans
			update(1,l1,l1+ans-1,1);
		}
    	if(op==2)printf("%d\n",query(1,l0,r0).max0);
    	continue;
		puts("AFTER UPD");
    	for(int i=1;i<=n*4;i++){
    		if(t[i].l){
    			cout<<"node "<<i<<endl;
    			cout<<t[i].l<<' '<<t[i].r<<endl;
    			cout<<t[i].max0<<endl;
    			cout<<t[i].ml0<<' '<<t[i].mr0<<endl;
    			cout<<t[i].sum0<<' '<<t[i].sum1<<endl;
    			cout<<t[i].tag<<endl;
    			cout<<endl;
			}
		}
	}
    return 0;
}
2024/12/31 18:20
加载中...