Sequence operation

Problem Description

lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]

Input

T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.

Output

For each output operation , output the result.

Sample Input

1
10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9

Sample Output

5
2
6
5
 
 
/*
        题意:首先给出一组数据:由0和1组成;
                     然后有5种操作:
                         0 a b表示把[a,b]区间的数全部变成0;
                         1 a b 表示把[a,b]区间的数全部变成1;
                         2 a b表示把[a,b]区间的0变成1、1变成0,也就是进行异或操作;
                         3 a b就是问你[a,b]区间总共有多少个1;
                         4 a b就是问你[a,b]区间最长的连续的1的个数。
*/
 
 
//标程:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 100010
struct ss
{
	int l,r,lone,lzero;
	int rone,rzero,max1,max0;
	int total,flag0,flag1,flag2,len;
}p[10*N];
int a[N];
int fmax(int x,int y) 
{
	return x>y?x:y;
}
int fmin(int x,int y) 
{
	return x<y?x:y;
}
void pushup(int k)
{
	p[k].lone=p[k*2].lone;
	if(p[2*k].lone==p[2*k].len) 
		p[k].lone+=p[2*k+1].lone;
    p[k].lzero=p[2*k].lzero;
	if(p[2*k].lzero==p[k*2].len)
		p[k].lzero+=p[2*k+1].lzero;
	p[k].rone=p[k*2+1].rone;
	if(p[2*k+1].rone==p[2*k+1].len) 
		p[k].rone+=p[2*k].rone;
    p[k].rzero=p[2*k+1].rzero;
	if(p[2*k+1].rzero==p[k*2+1].len)
		p[k].rzero+=p[2*k].rzero;
	p[k].max1=fmax(p[2*k].max1,p[2*k+1].max1);
	p[k].max1=fmax(p[k].max1,p[2*k].rone+p[2*k+1].lone);
	p[k].max0=fmax(p[2*k].max0,p[2*k+1].max0);
	p[k].max0=fmax(p[k].max0,p[2*k].rzero+p[2*k+1].lzero);
	p[k].total=p[2*k].total+p[2*k+1].total;
}
void build(int x,int y,int k)
{
	p[k].l=x, p[k].r=y, p[k].len=(y-x+1);
	p[k].flag0=p[k].flag1=p[k].flag2=0;
	if(x==y)
	{
		if(a[x]==1)
		{
			 p[k].max1=p[k].total=p[k].lone=p[k].rone=1;
			 p[k].lzero=p[k].rzero=p[k].max0=0;
		}
		else 
		{
			p[k].max1=p[k].total=p[k].lone=p[k].rone=0;
			p[k].lzero=p[k].rzero=p[k].max0=1;
		}
		return ;
	}
	int mid=(x+y)/2;
	build(x,mid,2*k);
	build(mid+1,y,2*k+1);
	pushup(k);
}
void pushdown(int k,int flag)
{
    if(flag==0)
	{
		p[2*k].flag0=p[2*k+1].flag0=1;
		p[2*k].flag1=p[2*k+1].flag1=0;
		p[2*k].flag2=p[2*k+1].flag2=0;
        p[k].flag0=0;


		p[2*k].lone=p[k*2].rone=p[2*k+1].lone=p[k*2+1].rone=0;
		p[2*k].total=p[2*k+1].total=0;
        p[2*k].max1=p[2*k+1].max1=0;


		p[2*k].max0=p[2*k].lzero=p[2*k].rzero=p[2*k].len;
		p[2*k+1].max0=p[2*k+1].lzero=p[k*2+1].rzero=p[2*k+1].len;
	}
	else if(flag==1)
	{
        p[2*k].flag0=p[2*k+1].flag0=0;
		p[2*k].flag1=p[2*k+1].flag1=1;
		p[2*k].flag2=p[2*k+1].flag2=0;
        p[k].flag1=0;
		p[2*k].lzero=p[k*2].rzero=p[2*k+1].lzero=p[k*2+1].rzero=0;
        p[2*k].max0=p[2*k+1].max0=0;
		p[2*k].total=p[2*k].max1=p[2*k].lone=p[2*k].rone=p[2*k].len;
		p[2*k+1].total=p[2*k+1].max1=p[2*k+1].lone=p[k*2+1].rone=p[2*k+1].len;
	}
	else 
	{
		p[2*k].flag2^=1;
		p[2*k+1].flag2^=1;
		p[k].flag2=0;
		swap(p[2*k].lone,p[2*k].lzero);
		swap(p[2*k].rone,p[2*k].rzero);
        swap(p[2*k].max0,p[2*k].max1);
		p[2*k].total=p[2*k].len-p[2*k].total;
		swap(p[2*k+1].lone,p[2*k+1].lzero);
		swap(p[2*k+1].rone,p[2*k+1].rzero);
		swap(p[2*k+1].max0,p[2*k+1].max1);
		p[2*k+1].total=p[2*k+1].len-p[2*k+1].total;
	}
}
void Insert(int x,int y,int k,int op)
{
    if(x==p[k].l && y==p[k].r)
	{
		if(op==0)
		{
			p[k].flag0=1,  p[k].flag1=p[k].flag2=0;
			p[k].lone=p[k].rone=0;
			p[k].max0=p[k].lzero=p[k].rzero=p[k].len;
			p[k].max1=p[k].total=0;
			return ;
		}
		else if(op==1)
		{
			p[k].flag1=1, p[k].flag0=p[k].flag2=0;
			p[k].max0=p[k].lzero=p[k].rzero=0;
			p[k].total=p[k].max1=p[k].lone=p[k].rone=p[k].len;
			return ;
		}
		else
		{
			p[k].flag2=p[k].flag2^1;
			if(p[k].flag0==1) pushdown(k,0);
			if(p[k].flag1==1) pushdown(k,1);
			swap(p[k].lone,p[k].lzero);
			swap(p[k].rone,p[k].rzero);
			swap(p[k].max1,p[k].max0);
			p[k].total=p[k].len-p[k].total;
			return ;
		}
	}
	if(p[k].l!=p[k].r)
	{
		if(p[k].flag0==1) pushdown(k,0);
		if(p[k].flag1==1) pushdown(k,1);
		if(p[k].flag2==1) pushdown(k,2);
	}
	int mid=(p[k].l+p[k].r)/2;
	if(y<=mid) Insert(x,y,2*k,op);
	else if(x>mid) Insert(x,y,2*k+1,op);
	else 
	{
		Insert(x,mid,2*k,op);
		Insert(mid+1,y,2*k+1,op);
	}
	pushup(k);
}
int sum1(int x,int y,int k)
{
	if(p[k].len==p[k].max1) return y-x+1;
	if(p[k].len==p[k].max0) return 0;
	if(x==p[k].l && y==p[k].r) return  p[k].total;
	if(p[k].l!=p[k].r)
	{
		if(p[k].flag0==1) pushdown(k,0);
		if(p[k].flag1==1) pushdown(k,1);
		if(p[k].flag2==1) pushdown(k,2);
	}
	int mid=(p[k].l+p[k].r)/2;
	if(y<=mid)   sum1(x,y,2*k);
	else if(x>mid)  sum1(x,y,2*k+1);
	else  return sum1(x,mid,2*k)+sum1(mid+1,y,2*k+1); 
}
int sum2(int x,int y,int k)
{
    if(p[k].len==p[k].max1) return y-x+1;
	if(p[k].len==p[k].max0) return 0;
	if(x==p[k].l && y==p[k].r) return  p[k].max1;
    if(p[k].l!=p[k].r)
	{
		if(p[k].flag0==1) pushdown(k,0);
		if(p[k].flag1==1) pushdown(k,1);
		if(p[k].flag2==1) pushdown(k,2);
	}
	int mid=(p[k].l+p[k].r)/2;
	if(y<=mid)  return sum2(x,y,2*k);
	else if(x>mid) return sum2(x,y,2*k+1);
	else  
	{
		int left=0, right=0,midn=0;
		midn=midn+fmin(mid-x+1,p[k*2].rone)+fmin(y-mid,p[2*k+1].lone);
		left=sum2(x,mid,2*k);
		right=sum2(mid+1,y,2*k+1);
		return fmax(midn,fmax(left,right));
	}
}
int main()
{
	//freopen("a.txt","r",stdin);
	int t,n,m,i,op,x,y;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++) scanf("%d",a+i);
		build(1,n,1);
		while(m--)
		{
			scanf("%d%d%d",&op,&x,&y);
			if(op==0)  Insert(x+1,y+1,1,op);
			else if(op==1) Insert(x+1,y+1,1,op);
			else if(op==2) Insert(x+1,y+1,1,op);
			else if(op==3) printf("%d\n",sum1(x+1,y+1,1));
			else if(op==4)   printf("%d\n",sum2(x+1,y+1,1));
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值