线段树30分求助,错的点都比标准答案少1
查看原帖
线段树30分求助,错的点都比标准答案少1
264596
Jorge_Filho楼主2022/8/18 20:15
#include<bits/stdc++.h>
using namespace std;
const int N=2e5,M=2e5;
int n,m,a[N+5],opt,x,y,z,w,st1,st2,l,r,mid;

struct node {
	int l,r;
	int tag;//1表示区间置0,2表示区间置1
	int sum;
	int l0,r0,q;
} t[4*N+5];

void Build(int p,int l,int r) {
	t[p].l=l;
	t[p].r=r;
	if(l==r) {
		t[p].sum=a[l];
		return ;
	}
	int md=(l+r)/2;
	Build(2*p,l,md);
	Build(2*p+1,md+1,r);
	t[p].sum=t[2*p].sum+t[2*p+1].sum;
	return ;
}

void Spread(int p) {
	if(t[p].tag) {
		t[2*p].tag=t[2*p+1].tag=t[p].tag;
		t[2*p].sum=(t[2*p].r-t[2*p].l+1)*(t[p].tag==2);
		t[2*p+1].sum=(t[2*p+1].r-t[2*p+1].l+1)*(t[p].tag==2);
		t[2*p].q=t[2*p].r0=t[2*p].l0=(t[2*p].r-t[2*p].l+1)-t[2*p].sum;
		t[2*p+1].q=t[2*p+1].r0=t[2*p+1].l0=(t[2*p+1].r-t[2*p+1].l+1)-t[2*p+1].sum;
		t[p].tag=0;
	}
	return ;
}

void Change(int p,int l,int r,int k) {
	if(t[p].l>=l&&t[p].r<=r) {
		t[p].tag=k;
		t[p].sum=(t[p].r-t[p].l+1)*(k==2);
		t[p].q=t[p].l0=t[p].r0=(t[p].r-t[p].l+1)-t[p].sum;
		return ;
	}
	Spread(p);
	int md=(t[p].l+t[p].r)/2;
	if(l<=md) Change(2*p,l,r,k);
	if(r>md) Change(2*p+1,l,r,k);
	t[p].sum=t[2*p].sum+t[2*p+1].sum;
	t[p].l0=t[2*p].l0+(t[2*p].l0==t[2*p].r-t[2*p].l+1)*t[2*p+1].l0;
	t[p].r0=t[2*p+1].r0+(t[2*p+1].r0==t[2*p+1].r-t[2*p+1].l+1)*t[2*p].r0;
	t[p].q=max(max(t[2*p].q,max(t[p].l0,t[p].r0)),max(t[2*p+1].q,t[2*p].r0+t[2*p+1].l0));
	return ;
}

int Ask(int p,int l,int r) {
	if(t[p].l>=l&&t[p].r<=r) return t[p].sum;
	Spread(p);
	int md=(t[p].l+t[p].r)/2;
	int res=0;
	if(l<=md) res+=Ask(2*p,l,r);
	if(r>md) res+=Ask(2*p+1,l,r);
	return res;
}

node Query(int p,int l,int r) {
	if(t[p].l>=l&&t[p].r<=r) return t[p];
	Spread(p);
	int md=(t[p].l+t[p].r)/2;
	node res;
	res.q=res.l0=res.r0=0;
	if(l<=md&&r>md) {
		node x=Query(2*p,l,r),y=Query(2*p+1,l,r);
		res.l0=x.l0+(x.l0==x.r-x.l+1)*y.l0;
		res.r0=y.r0+(y.r0==y.r-y.l+1)*x.r0;
		res.q=max(max(x.q,max(x.l0,x.r0)),max(y.q,x.r0+y.l0));
		return res;
	}
	if(l<=md)  return Query(2*p,l,r);
	if(r>md)  return Query(2*p+1,l,r);
	return res;
}

int main() {
	freopen("head.in","r",stdin);
	freopen("head.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) a[i]=1;
	Build(1,1,n);
	for(int i=1; i<=m; i++) {
		scanf("%d%d%d",&opt,&x,&y);
		if(!opt) {
			Change(1,x,y,1);
			continue;
		}
		if(opt==1) {
			scanf("%d%d",&z,&w);
			st1=Ask(1,x,y);
			Change(1,x,y,1);
			st2=Ask(1,z,w);
			mid=w;
			if(st1<w-z+1-st2) {//二分到第一个0的个数达标的位置
				l=z;
				r=w;
				while(l<r) {
					mid=(l+r)>>1;
					if(mid-z+1-Ask(1,z,mid)>=st1) r=mid;
					else l=mid+1;
				}
				mid=l;
			}
			Change(1,z,mid,2);
			continue;
		}
		printf("%d\n",Query(1,x,y).q);
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}

挂掉的点之一:

输入:

100 13
1 69 71 9 16
0 83 87
1 9 37 49 54
1 28 85 6 37
1 15 25 57 88
1 6 29 28 51
1 6 94 22 68
1 5 95 70 80
1 28 29 49 51
1 3 7 22 85
1 1 94 35 65
1 91 96 27 67
2 43 62

程序输出:

12

标准输出:

13
2022/8/18 20:15
加载中...