列表

详情


NC220370. J最长连续相同数字的长度

描述

给定一个01串,现在有以下5种操作

  1. 将[l,r]之间的数字取反

  2. 将[l,r]之间的数字反转

  3. 将[l,r]之间的数字从小到大排序

  4. 将[l,r]之间的数字置0

  5. 将[l,r]之间的数字置1

每次操作之后,输出当前的最长连续相同字符串的长度


输入描述

第一行有两个数字n,q表示01串长度和询问次数

第二行有一个长度位n的01串

接下来q行每行3个数字op,l,r表示操作种类,修改的范围

输出描述

q行,每行一个数字,表示最长连续相同数字的长度。

示例1

输入:

8 8
00000000
1 1 3
2 2 7
2 2 4
2 5 6
2 5 5
3 1 8
1 4 5
3 6 8

输出:

5
4
4
3
3
5
5
5

说明:


示例2

输入:

7 7
0111111
3 3 7
1 1 7
2 1 4
2 2 6
1 1 6
2 1 2
1 2 7

输出:

6
6
3
3
3
3
2

说明:


示例3

输入:

8 3
00000000
5 1 1
5 2 4
4 1 2

输出:

7
4
4

说明:


原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 659ms, 内存消耗: 7032K, 提交时间: 2021-04-01 20:31:01

#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
using namespace std;
#define N 200005
int n,m,cnt,root;
char f[N];
inline void read(int &p)
{
	p=0;
	int f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') p=p*10+(ch-'0'),ch=getchar();
	p*=f;
}

struct node{
	int siz,key,ch[2],val,lmax[2],rmax[2],mx[2],sum1,RRev;
	int cov;
	bool rev;
	inline void Rev(){
		rev^=1;
		swap(lmax[0],lmax[1]);
		swap(rmax[0],rmax[1]);
		swap(mx[0],mx[1]);
		if(cov!=-1)cov^=1;
		sum1=siz-sum1;
		val^=1;
	}
	inline void Cov(int d){
		val=d;
		cov=d;
		sum1=(d?siz:0);
		for(int i=0;i<=1;i++){
			lmax[i]=rmax[i]=mx[i]=((d==i)?siz:0);
		}
	}
	void pushr(){
		swap(ch[0],ch[1]);
		swap(lmax[0],rmax[0]);
		swap(lmax[1],rmax[1]);
		RRev^=1;
	}
}t[N];
int NewNode(int data){
	int k=++cnt;
	t[k].val=t[k].sum1=data;
	t[k].siz=1;
	t[k].key=rand();
	t[k].ch[0]=t[k].ch[1]=0;
	t[k].rev=0;
	t[k].cov=-1;
	t[k].RRev=0;
	for(int i=0;i<=1;i++){
		t[k].lmax[i]=t[k].rmax[i]=t[k].mx[i]=(data==i);
	}
	return k;
}
inline void update(int k){
	t[k].siz=t[t[k].ch[0]].siz+t[t[k].ch[1]].siz+1;
	t[k].sum1=t[t[k].ch[0]].sum1+t[t[k].ch[1]].sum1+t[k].val;
	for(int i=0;i<=1;i++){
		t[k].lmax[i]=t[t[k].ch[0]].lmax[i];
		t[k].rmax[i]=t[t[k].ch[1]].rmax[i];
		t[k].mx[i]=max(t[t[k].ch[0]].mx[i],t[t[k].ch[1]].mx[i]);
		if(t[k].val==i){
			if(t[t[k].ch[0]].sum1==(i?t[t[k].ch[0]].siz:0)){
				t[k].lmax[i]+=1+t[t[k].ch[1]].lmax[i];
			}
			if(t[t[k].ch[1]].sum1==(i?t[t[k].ch[1]].siz:0)){
				t[k].rmax[i]+=1+t[t[k].ch[0]].rmax[i];
			}
			t[k].mx[i]=max(t[k].mx[i],t[t[k].ch[0]].rmax[i]+1+t[t[k].ch[1]].lmax[i]);
		}
	}
}
inline void pushdown(int k){
	if(t[k].rev){
		t[t[k].ch[0]].Rev();
		t[t[k].ch[1]].Rev();
		t[k].rev=0;
	}
	if(t[k].cov!=-1){
		t[t[k].ch[0]].Cov(t[k].cov);
		t[t[k].ch[1]].Cov(t[k].cov);
		t[k].cov=-1;
	}
	if(t[k].RRev){
		t[t[k].ch[0]].pushr(),t[t[k].ch[1]].pushr();
		t[k].RRev=0;
	}
}
int Merge(int l,int r){
	if(!l||!r)return l+r;
	pushdown(l),pushdown(r);
	if(t[l].key<t[r].key){
		t[l].ch[1]=Merge(t[l].ch[1],r);
		update(l);
		return l;
	}
	else{
		t[r].ch[0]=Merge(l,t[r].ch[0]);
		update(r);
		return r;
	}
}
void Split(int k,int data,int &l,int &r){
	if(!k){
		l=r=0;
		return ;
	}
	pushdown(k);
	if(t[t[k].ch[0]].siz+1<=data){
		l=k;
		Split(t[k].ch[1],data-t[t[k].ch[0]].siz-1,t[k].ch[1],r);
	}
	else{
		r=k;
		Split(t[k].ch[0],data,l,t[k].ch[0]);
	}
	update(k);
}
inline void Change(int x,int y,int d){
	int l,p,r;
	Split(root,y,l,r);
	Split(l,x-1,l,p);
	t[p].Cov(d);
	root=Merge(Merge(l,p),r);
}
inline void Rever(int x,int y){
	int l,p,r;
	Split(root,y,l,r);
	Split(l,x-1,l,p);
	t[p].pushr();
	root=Merge(Merge(l,p),r);
}
inline void Reverse(int x,int y){
	int l,p,r;
	Split(root,y,l,r);
	Split(l,x-1,l,p);
	t[p].Rev();
	root=Merge(Merge(l,p),r);
}
inline int Count1(int x,int y){
	int l,p,r;
	Split(root,y,l,r);
	Split(l,x-1,l,p);
	int ans=t[p].sum1;
	root=Merge(Merge(l,p),r);
	return ans;
}
inline int Ask_MX(int x,int y){
	int l,p,r;
	Split(root,y,l,r);
	Split(l,x-1,l,p);
	int ans=max(t[p].mx[0],t[p].mx[1]);
	root=Merge(Merge(l,p),r);
	return ans;
}
void output(int x)
{
	if(!x)	return;
	pushdown(x);
	output(t[x].ch[0]);
	printf("%d ",t[x].val);
	output(t[x].ch[1]);
}
int main()
{
	srand(time(0));
	read(n);read(m);
	cin>>f+1;
	for(int i=1;i<=n;i++)
	{
		if(f[i]=='0') root=Merge(root,NewNode(0));
		else root=Merge(root,NewNode(1));
	}
	
	for(int i=1;i<=m;i++)
	{
		int l,r,opt;
		read(opt);read(l);read(r);
		switch(opt)
		{
			case 1:
			{
				Reverse(l,r);
				break;
			}
			case 2:
			{
				Rever(l,r);
				break;
			}
			case 3:
			{
				int X=Count1(l,r);
				if(l<=l+(r-l+1-X)-1) Change(l,l+(r-l+1-X)-1,0);
				if(X>=1) Change(l+(r-l+1-X),r,1);
				break;
			}
			case 4:
			{
				Change(l,r,0);
				break;
			}
			case 5:
			{
				Change(l,r,1);
				break;
			}
		}
		printf("%d\n",Ask_MX(1,n));
	}
	return 0;
}

上一题