关于暴力过了。
查看原帖
关于暴力过了。
993404
harmis_yz楼主2024/3/12 16:53

这题我区间覆盖写挂了。然后把区间覆盖的代码变成了暴力单点修改,结果过了……

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define il inline
#define pii pair<int,int>
#define x first
#define y second
#define gc getchar()
#define rd read()
#define debug() puts("------------")

namespace yzqwq{
	il int read(){
		int x=0,f=1;char ch=gc;
		while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc;}
		while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=gc;
		return x*f;
	}
	il int qmi(int a,int b,int p){
		int ans=1;
		while(b){
			if(b&1) ans=ans*a%p;
			a=a*a%p,b>>=1;
		}
		return ans;
	}
	il auto max(auto a,auto b){return (a>b?a:b);}
	il auto min(auto a,auto b){return (a<b?a:b);}
	il int gcd(int a,int b){
		if(!b) return a;
		return gcd(b,a%b);
	}
	il int lcm(int a,int b){
		return a/gcd(a,b)*b;
	}
	il void exgcd(int a,int b,int &x,int &y){
		if(!b) return x=1,y=0,void(0);
		exgcd(b,a%b,x,y);
		int t=x;
		x=y,y=t-a/b*x;
		return ;
	}
	mt19937 rnd(time(0));
}
using namespace yzqwq;

const int N=2e5+10;
int n,m,a[N];
struct Tree{
	int l,r;
	int tag1,tag2;//区间覆盖,区间翻转
	int lmax0,lmax1,rmax0,rmax1;
	int mx0,mx1;
	int cnt0,cnt1; 
}tr[N<<2];

il void up(int now){
	tr[now].lmax0=tr[now<<1].lmax0;
	if(tr[now<<1].lmax0==(tr[now<<1].r-tr[now<<1].l+1)) tr[now].lmax0+=tr[now<<1|1].lmax0;
	tr[now].lmax1=tr[now<<1].lmax1;
	if(tr[now<<1].lmax1==(tr[now<<1].r-tr[now<<1].l+1)) tr[now].lmax1+=tr[now<<1|1].lmax1;
	
	tr[now].rmax0=tr[now<<1|1].rmax0;
	if(tr[now<<1|1].rmax0==(tr[now<<1|1].r-tr[now<<1|1].l+1)) tr[now].rmax0+=tr[now<<1].rmax0;
	tr[now].rmax1=tr[now<<1|1].rmax1;
	if(tr[now<<1|1].rmax1==(tr[now<<1|1].r-tr[now<<1|1].l+1)) tr[now].rmax1+=tr[now<<1].rmax1;
	
	tr[now].mx0=max(tr[now<<1].mx0,tr[now<<1|1].mx0);
	tr[now].mx0=max(tr[now].mx0,tr[now<<1].rmax0+tr[now<<1|1].lmax0);
	tr[now].mx0=max({tr[now].mx0,tr[now].lmax0,tr[now].rmax0});
	
	tr[now].mx1=max(tr[now<<1].mx1,tr[now<<1|1].mx1);
	tr[now].mx1=max(tr[now].mx1,tr[now<<1].rmax1+tr[now<<1|1].lmax1);
	tr[now].mx1=max({tr[now].mx1,tr[now].lmax1,tr[now].rmax1});
	
	tr[now].cnt0=tr[now<<1].cnt0+tr[now<<1|1].cnt0;
	tr[now].cnt1=tr[now<<1].cnt1+tr[now<<1|1].cnt1;
	
	return ;
}
il void down(int now){
	if(tr[now].tag1!=-1){//有区间覆盖
		tr[now<<1].tag2=tr[now<<1|1].tag2=0;
		tr[now<<1].tag1=tr[now<<1|1].tag1=tr[now].tag1;
		tr[now<<1].lmax0=tr[now<<1].lmax1=tr[now<<1|1].lmax0=tr[now<<1|1].lmax1=0;
		tr[now<<1].rmax0=tr[now<<1].rmax1=tr[now<<1|1].rmax0=tr[now<<1|1].rmax1=0;
		tr[now<<1].mx0=tr[now<<1|1].mx0=0;
		tr[now<<1].mx1=tr[now<<1|1].mx1=0;
		tr[now<<1].cnt0=tr[now<<1|1].cnt0=0;
		tr[now<<1].cnt1=tr[now<<1|1].cnt1=0;
		
		if(tr[now].tag1==0){
			tr[now<<1].cnt0=tr[now<<1].mx0=tr[now<<1].lmax0=tr[now<<1].rmax0=(tr[now<<1].r-tr[now<<1].l+1);
			tr[now<<1|1].cnt0=tr[now<<1|1].mx0=tr[now<<1|1].lmax0=tr[now<<1|1].rmax0=(tr[now<<1|1].r-tr[now<<1|1].l+1);
		}
		else if(tr[now].tag1==1){
			tr[now<<1].cnt1=tr[now<<1].mx1=tr[now<<1].lmax1=tr[now<<1].rmax1=(tr[now<<1].r-tr[now<<1].l+1);
			tr[now<<1|1].cnt1=tr[now<<1|1].mx1=tr[now<<1|1].lmax1=tr[now<<1|1].rmax1=(tr[now<<1|1].r-tr[now<<1|1].l+1);
		}
		tr[now].tag1=-1;
	}
	if(tr[now].tag2!=0){//有区间翻转
		if(tr[now<<1].tag1!=-1) tr[now<<1].tag1^=1;
		if(tr[now<<1|1].tag1!=-1) tr[now<<1|1].tag1^=1;
		tr[now<<1].tag2^=1,tr[now<<1|1].tag2^=1;
		
		swap(tr[now<<1].cnt0,tr[now<<1].cnt1),
		swap(tr[now<<1].lmax0,tr[now<<1].lmax1),
		swap(tr[now<<1].rmax0,tr[now<<1].rmax1),
		swap(tr[now<<1].mx0,tr[now<<1].mx1);
		
		swap(tr[now<<1|1].cnt0,tr[now<<1|1].cnt1),
		swap(tr[now<<1|1].lmax0,tr[now<<1|1].lmax1),
		swap(tr[now<<1|1].rmax0,tr[now<<1|1].rmax1),
		swap(tr[now<<1|1].mx0,tr[now<<1|1].mx1);
		
		tr[now].tag2=0;	 
	}
	return ;
}
il void build(int now,int l,int r){
	tr[now].l=l,tr[now].r=r,tr[now].tag1=-1,tr[now].tag2=0;
	if(l==r){
		if(a[l]==0) tr[now].cnt0=tr[now].lmax0=tr[now].rmax0=tr[now].mx0=1;
		if(a[l]==1) tr[now].cnt1=tr[now].lmax1=tr[now].rmax1=tr[now].mx1=1;
		return ;
	}
	int mid=l+r>>1;
	build(now<<1,l,mid),build(now<<1|1,mid+1,r);
	return up(now),void(0);
}
il void insert1(int now,int l,int r,int k){//区间覆盖 
//	if(tr[now].l>=l&&tr[now].r<=r){
	if(tr[now].l==tr[now].r){
		tr[now].cnt0=tr[now].cnt1=0;
		tr[now].lmax0=tr[now].lmax1=0;
		tr[now].mx0=tr[now].mx1=0;
		tr[now].rmax0=tr[now].rmax1=0;
		tr[now].tag2=0,tr[now].tag1=k;
		if(k==0) tr[now].cnt0=tr[now].lmax0=tr[now].rmax0=tr[now].mx0=tr[now].r-tr[now].l+1;
		if(k==1) tr[now].cnt1=tr[now].lmax1=tr[now].rmax1=tr[now].mx1=tr[now].r-tr[now].l+1;
		return ;
	}
	down(now);
	int mid=tr[now].l+tr[now].r>>1;
	if(l<=mid) insert1(now<<1,l,r,k);
	if(mid<r) insert1(now<<1|1,l,r,k);
	return up(now),void(0);
}
il void insert2(int now,int l,int r){//区间翻转
	if(tr[now].l>=l&&tr[now].r<=r){
		swap(tr[now].cnt0,tr[now].cnt1);
		swap(tr[now].lmax0,tr[now].lmax1);
		swap(tr[now].mx0,tr[now].mx1);
		swap(tr[now].rmax0,tr[now].rmax1);
		tr[now].tag2^=1;
		return ;
	}
	down(now);
	int mid=tr[now].l+tr[now].r>>1;
	if(l<=mid) insert2(now<<1,l,r);
	if(mid<r) insert2(now<<1|1,l,r);
	return up(now),void(0);
}
il int query1(int now,int l,int r){//区间1的数量 
	if(tr[now].l>=l&&tr[now].r<=r) return tr[now].cnt1;
	down(now);
	int ans=0,mid=tr[now].l+tr[now].r>>1;
	if(l<=mid) ans+=query1(now<<1,l,r);
	if(mid<r) ans+=query1(now<<1|1,l,r);
	return up(now),ans;
}
il Tree query2(int now,int l,int r){//区间连续1的数量
	if(tr[now].l>=l&&tr[now].r<=r) return tr[now];
	down(now);
	Tree ans={0,0,0,0,0,0,0,0,0,0,0,0};
	int mid=tr[now].l+tr[now].r>>1;
	if(l<=mid) ans=query2(now<<1,l,r);
	if(mid<r){
		Tree ans2=query2(now<<1|1,l,r);	
		ans.mx1=max(ans.mx1,ans2.mx1);
		ans.mx1=max(ans.mx1,ans.rmax1+ans2.lmax1);
		if(ans.lmax1==mid-max(l,tr[now].l)+1) ans.lmax1+=ans2.lmax1;
		int rmax1=ans2.rmax1;
		if(rmax1==min(r,tr[now].r)-(mid+1)+1) rmax1+=ans.rmax1;
		ans.rmax1=rmax1;
		ans.mx1=max({ans.mx1,ans.lmax1,ans.rmax1});
	}
	return up(now),ans;
}

il void solve(){
	n=rd,m=rd;
	for(re int i=1;i<=n;++i) a[i]=rd;
	build(1,1,n);
	for(re int i=1;i<=m;++i){
		int op=rd,l=rd+1,r=rd+1;
		if(op==0) insert1(1,l,r,0);
		else if(op==1) insert1(1,l,r,1);
		else if(op==2) insert2(1,l,r);
		else if(op==3){
			int ans=query1(1,l,r);
			printf("%lld\n",ans);
		}
		else if(op==4){
			Tree ans=query2(1,l,r);
			printf("%lld\n",ans.mx1);
		}
//		for(re int j=1;j<=n;++j){
//			cout<<query1(1,j,j)<<" ";
//		}
//		cout<<"\n";
	}
	return ;
}

signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	int t=1;while(t--)
	solve();
	return 0;
}
/*
10 11
0 1 0 0 1 1 1 1 0 1
3 0 9
0 0 0
0 1 3
4 1 3
4 1 5
2 1 5
4 1 5
1 5 5
4 1 5
1 4 4
4 1 5
*/

第 135 行是改的暴力。

2024/3/12 16:53
加载中...