求大佬找问题谢谢
  • 板块学术版
  • 楼主gmx0424
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/11/3 21:57
  • 上次更新2023/11/4 08:45:01
查看原帖
求大佬找问题谢谢
890233
gmx0424楼主2023/11/3 21:57
/*
题目:3个修改,全部0,1,取反 
	  2个查询 有多少个1(区间和),最多连续1(最大子段和)
	  
思路: 类似求最大子段和
	
	b:区间1的个数 
	lb:左端点开始区间1的长度 
	rb:右端点结束区间1的长度 
	mb:区间1最大长度 
	c:区间0的个数 
	lc:左端点开始区间0的长度
	rc:右端点结束区间0的长度 
	mc:区间0最大长度 
	len:区间长度 
	tag:赋值,-1表示无,0,1 
	rev:取反 0,1 
	
	优先级:赋值>取反
			赋值时候,取反清空
			
	更新:
		b,c:直接加
		lb:看左边0,如果没有0,那么左右加,否则继承左边
		lc:看右边1......
		rb,rc同理
		mb=max( max(l.mb,r.mb),l.rb+r.lb);
		mc同理 
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, m;
int a[maxn];
struct node{
	int b,lb,rb,mb;
	int c,lc,rc,mc;
	int len;
	int tag;
	int rev;
} v[maxn << 2] ;


void pushup(int rt){
	
	v[rt].b = v[rt<<1].b + v[rt<<1|1].b;
	v[rt].lb = v[rt<<1].lc ? v[rt<<1].lb : v[rt<<1].b + v[rt<<1|1].lb;
	v[rt].rb = v[rt<<1|1].rc ? v[rt<<1|1].rb : v[rt<<1|1].b + v[rt<<1].rb;
	v[rt].mb = max( max(v[rt<<1].mb, v[rt<<1|1].mb) , v[rt<<1].rb + v[rt<<1|1].lb);
	
	v[rt].c = v[rt<<1].c + v[rt<<1|1].c;
	v[rt].lc = v[rt<<1].lb ? v[rt<<1].lc : v[rt<<1].c + v[rt<<1|1].lc;
	v[rt].rc = v[rt<<1|1].rb ? v[rt<<1|1].rc : v[rt<<1|1].c + v[rt<<1].rc;
	v[rt].mc = max( max(v[rt<<1].mc, v[rt<<1|1].mc) , v[rt<<1].rc + v[rt<<1|1].lc);
}


void merge(int rt, int op){
	node &t = v[rt];
	if (op == 0) 
	{
		t.b = t.lb = t.rb = t.mb = 0;
		t.c = t.lc = t.rc = t.mc = t.len;
		t.tag = 0;//
		t.rev = 0;
	}
	
	if (op == 1)
	{
		t.c = t.lc = t.rc = t.mc = 0;
		t.b = t.lb = t.rb = t.mb = t.len;
		t.tag = 1;//
		t.rev = 0;
	}
	
	if (op == 2)
	{
		swap(t.b, t.c);
		swap(t.lb,t.lc);
		swap(t.rb,t.rc);
		swap(t.mb,t.mc);
		t.rev ^= 1;
	}
}



void pushdown(int rt, int l, int r){
	if (v[rt].tag == 0){
		merge(rt << 1, 0);// 修改左右儿子 
		merge(rt<<1|1,0); 
	}
	
	if(v[rt].tag == 1){
		merge(rt<<1,1); 
		merge(rt<<1|1,1); 
	}
	
	if(v[rt].rev){
		merge(rt<<1,2);
	    merge(rt<<1|1,2); 
	}
	
	v[rt].tag = -1;
	v[rt].rev = 0;
}


void build(int rt, int l, int r){
	int k = a[l];//看当前是0还是1,k^1--->取反 
	v[rt] = {k,k,k,k,k^1,k^1,k^1,k^1,r-l+1,-1,0};
	if(l == r) return;
	int mid = (l + r) >> 1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	pushup(rt);
}


void update(int rt,int l,int r,int ql,int qr,int op){
	if (qr < l || ql > r){
		return ;
	}
	
	if (ql <= l && r <= qr){
		merge(rt,op);
		return;
	}
	pushdown(rt,l,r);
	int mid = (l + r)>>1;
	update(rt<<1,l,mid,ql,qr,op);
	update(rt<<1|1,mid+1,r,ql,qr,op);
	pushup(rt);
}


node query(int rt,int l,int r,int ql,int qr){
	if (qr < l || ql > r){
		return {};
	}
	
	if (ql <= l && r <= qr){
		return v[rt];
	}
	pushdown(rt,l,r);
	int mid = (l+r)>>1;
 	pushup(rt);
 	return v[rt];
}	


int main () {
	cin >> n >> m;
	for (int i = 1; i <= n ;i++){
		cin >> a[i];
	}
	
	build(1,1,n);
	
	while (m--){
		int k, l, r;
		cin >> k >> l >> r;
		if (k == 0){
			update(1,1,n,l,r,k);
		}else if (k==1){
			update(1,1,n,l,r,k);
		}else if (k==2){
			update(1,1,n,l,r,k);
		}else if (k == 3){
			node ans = query(1,1,n,l,r);
			cout << ans.b << '\n';
		}else if (k==4){
			node ans = query(1,1,n,l,r);
			cout << ans.mb << '\n';
		}
	}
	return 0;
}
2023/11/3 21:57
加载中...