求调,玄关,25pts
查看原帖
求调,玄关,25pts
622724
l_615楼主2024/5/3 15:04

Link

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int const N=2e5+10;
int n,m;
int e,la,ra,lb,rb;
struct tree{
	int maxn,sum,tag,rt,lt,len;
}tr[N<<2];

int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
void push_up(int p)
{
	tr[p].sum=tr[ls(p)].sum+tr[rs(p)].sum;
	if(tr[ls(p)].lt==tr[ls(p)].len)tr[p].lt=tr[ls(p)].len+tr[rs(p)].lt;
	else tr[p].lt=tr[ls(p)].lt;
	if(tr[rs(p)].rt==tr[rs(p)].len)tr[p].rt=tr[rs(p)].len+tr[ls(p)].rt;
	else tr[p].rt=tr[rs(p)].rt;
	tr[p].maxn=max(tr[ls(p)].maxn,max(tr[rs(p)].maxn,tr[ls(p)].rt+tr[rs(p)].lt));
}
void build(int l,int r,int p)
{
	if(l==r)
	{
		tr[p].sum=tr[p].len=1;
		return;
	}
	tr[p].len=r-l+1;
	int mid=(l+r)>>1;
	build(l,mid,ls(p));
	build(mid+1,r,rs(p));
	push_up(p);
}
void push_down_dig(int p)//挖洞的push_down 
{
	tr[ls(p)].sum=tr[rs(p)].sum=0;
	tr[ls(p)].tag=tr[rs(p)].tag=1;
	tr[ls(p)].lt=tr[ls(p)].rt=tr[ls(p)].maxn=tr[ls(p)].len;
	tr[rs(p)].lt=tr[rs(p)].rt=tr[rs(p)].maxn=tr[rs(p)].len;
}
void push_down_save(int p)//填洞的push_down 
{
	tr[ls(p)].sum=tr[ls(p)].len;
	tr[rs(p)].sum=tr[rs(p)].len;
	tr[ls(p)].tag=tr[rs(p)].tag=2;
	tr[ls(p)].lt=tr[ls(p)].rt=tr[ls(p)].maxn=tr[rs(p)].lt=tr[rs(p)].rt=tr[rs(p)].maxn=0;
}
void push_down(int p)
{
	if(tr[p].tag==1)
	 push_down_dig(p);
	if(tr[p].tag==2)
	 push_down_save(p);
	tr[p].tag=0;
}
void update_dig(int nl,int nr,int l,int r,int p)//挖洞 
{
	if(nl<=l&&r<=nr)
	{
		tr[p].sum=0;
		tr[p].tag=1;
		tr[p].lt=tr[p].rt=tr[p].maxn=tr[p].len;
		return;
	}
	int mid=(l+r)>>1;
	push_down(p);
	if(nl<=mid)update_dig(nl,nr,l,mid,ls(p));
	if(nr>mid)update_dig(nl,nr,mid+1,r,rs(p));
	push_up(p);
}
int query_save(int nl,int nr,int l,int r,int p)//有多少脑子能挖出来 
{
	if(nl<=l&&r<=nr)
	{
		return tr[p].sum;
	}
	int res=0;
	push_down(p);
	int mid=(l+r)>>1;
	if(nl<=mid)res+=query_save(nl,nr,l,mid,ls(p));
	if(nr>mid)res+=query_save(nl,nr,mid+1,r,rs(p));
	return res;
}
void update_save2(int nl,int nr,int l,int r,int p)//填洞 
{
	if(nl<=l&&r<=nr)
	{
		tr[p].sum=tr[p].len;
		tr[p].tag=2;
		tr[p].lt=tr[p].rt=tr[p].maxn=0;
		return;
	}
	int mid=(l+r)>>1;
	push_down(p);
	if(nl<=mid)update_save2(nl,nr,l,mid,ls(p));
	if(nr>mid)update_save2(nl,nr,mid+1,r,rs(p));
	push_up(p);
}
int query_save2(int nl,int nr,int l,int r,int p)//有多少洞能填进去 
{
	if(nl<=l&&r<=nr)
	{
		return tr[p].len-tr[p].sum;
	}
	int res=0;
	int mid=(l+r)>>1;
	push_down(p);
	if(nl<=mid)res+=query_save2(nl,nr,l,mid,ls(p));
	if(nr>mid)res+=query_save2(nl,nr,mid+1,r,rs(p));
	return res;
}
void update_save()//先挖出来后填洞 
{
	int x=query_save(la,ra,1,n,1);
	if(x==0)return;
	update_dig(la,ra,1,n,1);
	int l=lb,r=rb+1;
	while(l+1<r)
	{
		int mid=(l+r)>>1;
		if(query_save2(lb,mid,1,n,1)<=x)l=mid;
		else r=mid;
	}
	update_save2(lb,l,1,n,1);
}
int query(int nl,int nr,int l,int r,int p)//找最大的洞 
{
	if(nl<=l&&r<=nr)
	{
		return tr[p].maxn;
	}
	push_down(p);
	int mid=(l+r)>>1;
	int res=0;
	if(nl<=mid)res=max(res,query(nl,nr,l,mid,ls(p)));
	if(nr>mid)res=max(res,query(nl,nr,mid+1,r,rs(p)));
	return res;
}
int main()
{
	scanf("%d%d",&n,&m);
	build(1,n,1);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&e);
		if(e==0)
		{
			scanf("%d%d",&la,&ra);
			update_dig(la,ra,1,n,1);
		}else if(e==1)
		{
			scanf("%d%d%d%d",&la,&ra,&lb,&rb);
			update_save();
		}else{
			scanf("%d%d",&la,&ra);
			printf("%d\n",query(la,ra,1,n,1));
		}
	}
}
2024/5/3 15:04
加载中...