题解 P2572序列操作

分析

对连续值和求和的询问都是比较板的,这里讲修改,赋值和翻转分别设置一个标记,思考它们的优先级,显然赋值高于翻转,所以在赋值时应清空翻转标记,在翻转时优先考虑能不能直接将赋值标记异或一,否则在改变自身即可。

Code


#include<bits/stdc++.h>
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
inline void read(int &res){
	char c;
	int f=1;
	res=0;
	c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')res=(res<<1)+(res<<3)+c-48,c=getchar();
	res*=f;
}
int n,m;
int cs[100005];
struct node{
	int sum1,sum0,qz1,qz0,hz1,hz0,lx0,lx1,len;
	int qf,fz;
}a[800005];
inline int max(int aa,int bb){return aa>bb?aa:bb;}
void build(int rt,int l,int r){
	a[rt].fz=-1;
	a[rt].len=r-l+1;
	if(l==r){
		if(cs[l]){
			a[rt].sum1=a[rt].qz1=a[rt].hz1=a[rt].lx1=1;
		}
		else a[rt].sum0=a[rt].qz0=a[rt].hz0=a[rt].lx0=1;
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	a[rt].qz0=a[ls].qz0+(a[ls].qz0==a[ls].len?a[rs].qz0:0);
	a[rt].qz1=a[ls].qz1+(a[ls].qz1==a[ls].len?a[rs].qz1:0);
	a[rt].hz0=a[rs].hz0+(a[rs].hz0==a[rs].len?a[ls].hz0:0);
	a[rt].hz1=a[rs].hz1+(a[rs].hz1==a[rs].len?a[ls].hz1:0);
	a[rt].sum0=a[ls].sum0+a[rs].sum0;
	a[rt].sum1=a[ls].sum1+a[rs].sum1;
	a[rt].lx0=max(a[ls].lx0,max(a[rs].lx0,max(a[rt].qz0,max(a[rt].hz0,a[ls].hz0+a[rs].qz0))));
	a[rt].lx1=max(a[ls].lx1,max(a[rs].lx1,max(a[rt].qz1,max(a[rt].hz1,a[ls].hz1+a[rs].qz1))));
}
inline void pushdown(int rt){
	if(a[rt].fz!=-1){
		a[ls].fz=a[rs].fz=a[rt].fz;
		a[ls].qf=a[rs].qf=0;
		if(a[rt].fz){
			a[ls].sum1=a[ls].qz1=a[ls].hz1=a[ls].lx1=a[ls].len;
			a[ls].sum0=a[ls].qz0=a[ls].hz0=a[ls].lx0=0;
			a[rs].sum1=a[rs].qz1=a[rs].hz1=a[rs].lx1=a[rs].len;
			a[rs].sum0=a[rs].qz0=a[rs].hz0=a[rs].lx0=0;
		}
		else {
			a[ls].sum0=a[ls].qz0=a[ls].hz0=a[ls].lx0=a[ls].len;
			a[ls].sum1=a[ls].qz1=a[ls].hz1=a[ls].lx1=0;
			a[rs].sum0=a[rs].qz0=a[rs].hz0=a[rs].lx0=a[rs].len;
			a[rs].sum1=a[rs].qz1=a[rs].hz1=a[rs].lx1=0;
		}
		a[rt].fz=-1;
	}
	if(a[rt].qf){
		if(a[ls].fz!=-1)a[ls].fz^=1;
		else a[ls].qf^=1;
		if(a[rs].fz!=-1)a[rs].fz^=1;
		else a[rs].qf^=1;
		swap(a[ls].qz0,a[ls].qz1);
		swap(a[ls].hz0,a[ls].hz1);
		swap(a[ls].sum0,a[ls].sum1);
		swap(a[ls].lx1,a[ls].lx0);
		swap(a[rs].qz0,a[rs].qz1);
		swap(a[rs].hz0,a[rs].hz1);
		swap(a[rs].sum0,a[rs].sum1);
		swap(a[rs].lx1,a[rs].lx0);
		a[rt].qf=0;
	}
}
void modify(int rt,int l,int r,int L,int R,int k){
	pushdown(rt);
	if(l>=L&&R>=r){
		if(k){
			a[rt].sum1=a[rt].qz1=a[rt].hz1=a[rt].lx1=a[rt].len;
			a[rt].sum0=a[rt].qz0=a[rt].hz0=a[rt].lx0=0;
			a[rt].fz=1;
		}
		else {
			a[rt].sum0=a[rt].qz0=a[rt].hz0=a[rt].lx0=a[rt].len;
			a[rt].sum1=a[rt].qz1=a[rt].hz1=a[rt].lx1=0;
			a[rt].fz=0;
		}
		a[rt].qf=0;
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=L)modify(ls,l,mid,L,R,k);
	if(mid<R)modify(rs,mid+1,r,L,R,k);
	a[rt].qz0=a[ls].qz0+(a[ls].qz0==a[ls].len?a[rs].qz0:0);
	a[rt].qz1=a[ls].qz1+(a[ls].qz1==a[ls].len?a[rs].qz1:0);
	a[rt].hz0=a[rs].hz0+(a[rs].hz0==a[rs].len?a[ls].hz0:0);
	a[rt].hz1=a[rs].hz1+(a[rs].hz1==a[rs].len?a[ls].hz1:0);
	a[rt].sum0=a[ls].sum0+a[rs].sum0;
	a[rt].sum1=a[ls].sum1+a[rs].sum1;
	a[rt].lx0=max(a[ls].lx0,max(a[rs].lx0,max(a[rt].qz0,max(a[rt].hz0,a[ls].hz0+a[rs].qz0))));
	a[rt].lx1=max(a[ls].lx1,max(a[rs].lx1,max(a[rt].qz1,max(a[rt].hz1,a[ls].hz1+a[rs].qz1))));
}
void rotate(int rt,int l,int r,int L,int R){
	pushdown(rt);
	if(l>=L&&R>=r){
		if(a[rt].fz!=-1)a[rt].fz^=1;
		else a[rt].qf^=1;
		swap(a[rt].qz0,a[rt].qz1);
		swap(a[rt].hz0,a[rt].hz1);
		swap(a[rt].sum0,a[rt].sum1);
		swap(a[rt].lx1,a[rt].lx0);
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=L)rotate(ls,l,mid,L,R);
	if(mid<R)rotate(rs,mid+1,r,L,R);
	a[rt].qz0=a[ls].qz0+(a[ls].qz0==a[ls].len?a[rs].qz0:0);
	a[rt].qz1=a[ls].qz1+(a[ls].qz1==a[ls].len?a[rs].qz1:0);
	a[rt].hz0=a[rs].hz0+(a[rs].hz0==a[rs].len?a[ls].hz0:0);
	a[rt].hz1=a[rs].hz1+(a[rs].hz1==a[rs].len?a[ls].hz1:0);
	a[rt].sum0=a[ls].sum0+a[rs].sum0;
	a[rt].sum1=a[ls].sum1+a[rs].sum1;
	a[rt].lx0=max(a[ls].lx0,max(a[rs].lx0,max(a[rt].qz0,max(a[rt].hz0,a[ls].hz0+a[rs].qz0))));
	a[rt].lx1=max(a[ls].lx1,max(a[rs].lx1,max(a[rt].qz1,max(a[rt].hz1,a[ls].hz1+a[rs].qz1))));
}
node query(int rt,int l,int r,int L,int R){
	//cout<<l<<" "<<r<<" "<<a[rt].sum1<<endl;
	if(l>=L&&R>=r)return a[rt];
	pushdown(rt);
	node aa,bb,ans;
	int mid=(l+r)>>1;
	if(mid<L)return query(rs,mid+1,r,L,R);
	if(mid>=R)return query(ls,l,mid,L,R);
	aa=query(ls,l,mid,L,R);
	bb=query(rs,mid+1,r,L,R);
	//cout<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<aa.sum1<<" "<<bb.sum1<<endl;
	ans.qz0=aa.qz0+(aa.qz0==aa.len?bb.qz0:0);
	ans.qz1=aa.qz1+(aa.qz1==aa.len?bb.qz1:0);
	ans.hz0=bb.hz0+(bb.hz0==bb.len?aa.hz0:0);
	ans.hz1=bb.hz1+(bb.hz1==bb.len?aa.hz1:0);
	ans.sum0=aa.sum0+bb.sum0;
	ans.sum1=aa.sum1+bb.sum1;
	ans.lx0=max(aa.lx0,max(bb.lx0,max(ans.qz0,max(ans.hz0,aa.hz0+bb.qz0))));
	ans.lx1=max(aa.lx1,max(bb.lx1,max(ans.qz1,max(ans.hz1,aa.hz1+bb.qz1))));
	ans.len=aa.len+bb.len;
	return ans;
}
int main()
{
	read(n);read(m);
	for(int i=1;i<=n;i++)read(cs[i]);
	build(1,1,n);
	while(m--){
		int op,l,r;
		read(op);read(l);read(r);
		l++;r++;
		if(op==0){
			modify(1,1,n,l,r,0);
		}
		if(op==1){
			modify(1,1,n,l,r,1);
		}
		if(op==2){
			rotate(1,1,n,l,r);
		}
		if(op==3){
			printf("%d\n",query(1,1,n,l,r).sum1);
		}
		if(op==4){
			printf("%d\n",query(1,1,n,l,r).lx1);
		}
	}
	return 0;
}

上一篇:串口通讯协议和RS-232的介绍以及USB/TTL转232模块的工作原理


下一篇:jsp遍历mysql数据库