线段树求助re一片
查看原帖
线段树求助re一片
505370
HHHHHHuang楼主2023/10/11 14:09

需要帮助,调了3天了

提交记录

https://www.luogu.com.cn/record/128713759

#include<bits/stdc++.h>
using namespace std;
long long h,x,y,x2,y2,v,summ;
long long n,m,add[1000005],sum[1000005],rr[1000005],ll[1000005],ads[1000005],ans[1000005];
void build(int k,int l,int r)
{
    if(l==r)
    {
        ans[k]=1;
		add[k]=0;sum[k]=0;
        return;
    }
    long long mid=(l+r)>>1;
    build((k<<1),l,mid);
    build((k<<1)^1,mid+1,r);
   ans[k]=ans[(k<<1)]+ans[(k<<1)^1];
}
void ad(int k,int l,int r,int o)
{
	if(o==-1)
	{
		rr[k]=0;ll[k]=0;sum[k]=0;
		add[k]=-1;ads[k]=1;ans[k]+=1*(r-l+1);	
	} 
	if(o==1)
	{
	//	cout<<r-l+1<<"\n";
		rr[k]=r-l+1;ll[k]=r-l+1;sum[k]=r-l+1;
		add[k]=1;ads[k]=0;ans[k]=0;
	}
}
void pushdown(int k,int r,int l,int mid)
{
	ad((k<<1),r,mid,add[k]);
	ad((k<<1)^1,mid+1,l,add[k]);
	add[k]=0;ads[k]=0;
}
long long ADD(int k,int r,int l,int x,int y)
{
	long long mid=(r+l)>>1;
    pushdown(k,r,l,mid);	
    if(r>=x&&l<=y)
    {
    //	cout<<k<<" "<<r<<" "<<l<<"*"<<" ";
        ad(k,r,l,-1);
        return 0;
    }
	if(x<=mid)ADD((k<<1),r,mid,x,y);
	if(y>mid)ADD((k<<1)^1,mid+1,l,x,y);
	sum[k]=max(max(sum[(k<<1)],sum[(k<<1)^1]),ll[(k<<1)]+rr[(k<<1)^1]);
	ans[k]=ans[(k<<1)]+ans[(k<<1)^1];
	if(rr[(k<<1)]==mid-r+1)rr[k]=rr[(k<<1)^1]+rr[(k<<1)];
	else rr[k]=rr[(k<<1)];
	if(ll[(k<<1)^1]==l-mid)ll[k]=ll[(k<<1)]+ll[(k<<1)^1];
	else ll[k]=ll[(k<<1)^1];
}
long long ADD2(int k,int r,int l,int x,int y)
{
//	cout<<k<<" "<<r<<" "<<l<<"\n"; 
	long long mid=(r+l)>>1;
    pushdown(k,r,l,mid);
    if(r>=x&&l<=y)
    {
        ad(k,r,l,1);
        return 0;
    }
	if(x<=mid)ADD2((k<<1),r,mid,x,y);
	if(y>mid)ADD2((k<<1)^1,mid+1,l,x,y);
	sum[k]=max(max(sum[(k<<1)],sum[(k<<1)^1]),ll[(k<<1)]+rr[(k<<1)^1]);
	ans[k]=ans[(k<<1)]+ans[(k<<1)^1];
	if(rr[(k<<1)]==mid-r+1)rr[k]=rr[(k<<1)^1]+rr[(k<<1)];
	else rr[k]=rr[(k<<1)];
	if(ll[(k<<1)^1]==l-mid)ll[k]=ll[(k<<1)]+ll[(k<<1)^1];
	else ll[k]=ll[(k<<1)^1];
}
int check(int k,int r,int l,int x,int y)
{
	long long mid=(r+l)>>1,ans1=0;
	pushdown(k,r,l,mid);	
	if(r>=x&&l<=y)
	{
		return ans[k];
	}
	if(x<=mid)ans1+=check((k<<1),r,mid,x,y);
	if(y>mid)ans1+=check((k<<1)^1,mid+1,l,x,y);
	return ans1;
}
long long check1(int k,int r,int l,int x,int y,int o)
{
//	cout<<k<<" "<<r<<" "<<l<<" "<<o<<" "<<sum[k]<<" "<<rr[k]<<" "<<ll[k]<<"\n";
	long long mid=(r+l)>>1,rr1=0,ll1=0;
	pushdown(k,r,l,mid);
	if(r>=x&&l<=y)
	{
		summ=max(summ,sum[k]);
		if(o==0)return rr[k];
		if(o==1)return ll[k];
	}
	if(x<=mid)ll1=check1((k<<1),r,mid,x,y,1);
	if(y>mid)rr1=check1((k<<1)^1,mid+1,l,x,y,0);
//	cout<<rr1<<" "<<ll1<<" "<<r<<" "<<mid<<" "<<mid+1<<" "<<l<<"\n";
	summ=max(summ,rr1+ll1);
	if(rr[(k<<1)]==mid-r+1)rr[k]=rr[(k<<1)^1]+rr[(k<<1)];
	else rr[k]=rr[(k<<1)];
	if(ll[(k<<1)^1]==l-mid)ll[k]=ll[(k<<1)]+ll[(k<<1)^1];
	else ll[k]=ll[(k<<1)^1];
	if(o==0)return rr[k];
	if(o==1)return ll[k];
}
int main()
{
    cin>>n>>m;
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
    	scanf("%lld",&h);
    	if(h==0)
    	{
    		scanf("%lld%lld",&x,&y);
			ADD2(1,1,n,x,y);
    	}
    	if(h==1)
    	{
    		scanf("%lld%lld%lld%lld",&x2,&y2,&x,&y);
    		int ll=0;
    		if(x2<=y)ll=check(1,1,n,min(x,x2),max(y,y2));
    		else ll=check(1,1,n,x,y)+check(1,1,n,x2,y2);
    		if(check(1,1,n,x2,y2)==0)continue; 
    		if(y>=x+ll)
			{
				int r=x,l=y;
				while(r<=l)
				{
					int mid=(r+l)/2,p=0;
					p=mid-x+1+check(1,1,n,mid+1,y);
					if(p>ll)l=mid-1;
					else r=mid+1;
				}
    			ADD(1,1,n,x2,y2);
				ADD(1,1,n,x,l);
				ADD2(1,1,n,x2,y2);
			}
    		else
			{
    			ADD(1,1,n,x,y);
    			ADD(1,1,n,x2,y2);	
				ADD2(1,1,n,x2,y2);
			}
    	}
    	if(h==2)
    	{
    		scanf("%lld%lld",&x,&y); 
    		summ=0;
    		check1(1,1,n,x,y,-1);
    		printf("%lld\n",summ);
    	}
    }
    return 0;
} 
2023/10/11 14:09
加载中...