社区讨论

只有sub#1过了,求条QWQ

P2572[SCOI2010] 序列操作参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mhjl9bnp
此快照首次捕获于
2025/11/04 04:24
4 个月前
此快照最后确认于
2025/11/04 04:24
4 个月前
查看原帖
救救我QWQ
CPP
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
const int N=1e6+7;
int n,m,a[N],ans,pre;
struct node
{
	int l,r,val;
	int sum,maxx;
	int maxl,maxr;
	int Imaxx,Imaxl,Imaxr;
}t[4*N];

void pushup(int id)
{
	t[id].sum=t[id*2].sum+t[id*2+1].sum;
	t[id].maxl=t[id*2].maxl;
	t[id].Imaxl=t[id*2+1].Imaxl;
	if(t[id].maxl==t[id*2].r-t[id*2].l+1)
	{
		t[id].maxl+=t[id*2+1].maxl;
	}
	if(t[id].Imaxl==t[id*2].r-t[id*2].l+1)
	{
		t[id].Imaxl+=t[id*2+1].Imaxl;
	}
	t[id].Imaxr=t[id*2+1].Imaxr;
	t[id].maxr=t[id*2+1].maxr;
	
	if(t[id].maxr==t[id*2+1].r-t[id*2+1].l+1)
	{
		t[id].maxr+=t[id*2].maxr;
	}
	if(t[id].Imaxr==t[id*2+1].r-t[id*2+1].l+1)
	{
		t[id].Imaxr+=t[id*2].Imaxr;
	}
	t[id].maxx=max(t[id*2].maxx,max(t[id*2+1].maxx,t[id*2].maxr+t[id*2+1].maxl));
   	t[id].Imaxx=max(t[id*2].Imaxx,max(t[id*2+1].Imaxx,t[id*2].Imaxr+t[id*2+1].Imaxl));
}

void build(int id,int l,int r)
{
	t[id].l=l;
	t[id].r=r;
	t[id].val=-1;
	if(l==r)
	{
		t[id].maxl=t[id].maxr=t[id].maxx=t[id].sum=a[l];
		t[id].Imaxl=t[id].Imaxr=t[id].Imaxx=a[l]^1;
		return;
	}
	int mid=(l+r)/2;
	build(id*2,l,mid);
	build(id*2+1,mid+1,r);
	pushup(id);
}

void change(int id)
{
	swap(t[id].maxl,t[id].Imaxl);
	swap(t[id].maxr,t[id].Imaxr);
	swap(t[id].maxx,t[id].Imaxx);
    t[id].sum=t[id].r-t[id].l+1-t[id].sum;
}

void downdate(int id)
{
	if(t[id].val<=1&&t[id].val>=0)
	{
        int tmp;
        tmp=(t[id*2].r-t[id*2].l+1);
        t[id*2].val=t[id].val;
        t[id*2].maxl=t[id*2].maxr=t[id*2].maxx=t[id*2].sum=tmp*t[id].val;
        t[id*2].Imaxl=t[id*2].Imaxr=t[id*2].Imaxx=tmp*(t[id].val^1);
        tmp=(t[id*2+1].r-t[id*2+1].l+1);
        t[id*2+1].val=t[id].val;
        t[id*2+1].maxl=t[id*2+1].maxr=t[id*2+1].maxx=t[id*2+1].sum=tmp*t[id].val;
        t[id*2+1].Imaxl=t[id*2+1].Imaxr=t[id*2+1].Imaxx=tmp*(t[id].val^1);		
	}
 
    else if(t[id].val==2)
    {
        if(t[id*2].val<=1&&t[id*2].val>=0)
        {
            int tmp=(t[id*2].r-t[id*2].l+1);
            t[id*2].maxl=t[id*2].maxr=t[id*2].maxx=t[id*2].sum=tmp*(t[id*2].val^1);
            t[id*2].Imaxl=t[id*2].Imaxr=t[id*2].Imaxx=tmp*t[id*2].val;
            t[id*2].val^=1;
        }
        else if(t[id*2].val==-1)
        {
            change(id*2);
			t[id*2].val=2;
        }
        else if(t[id*2].val==2)
        {
            change(id*2);
			t[id*2].val=-1;
        }
        if(t[id*2+1].val<=1&&t[id*2+1].val>=0)
        {
            int tmp=(t[id*2+1].r-t[id*2+1].l+1);
            t[id*2+1].maxl=t[id*2+1].maxr=t[id*2+1].maxx=t[id*2+1].sum=tmp*(t[id*2+1].val^1);
            t[id*2+1].Imaxl=t[id*2+1].Imaxr=t[id*2+1].Imaxx=tmp*t[id*2+1].val;
            t[id*2+1].val^=1;
        }
        
        else if(t[id*2+1].val==-1)
        {
            change(id*2+1);
			t[id*2+1].val=2;
        }
        
        else if(t[id*2+1].val==2)
        {
            change(id*2+1);
			t[id*2+1].val=-1;
        }
    }
    
	t[id].val=-1;	
}//恶心!!!!! 

void update(int id,int l,int r,int op)
{
	if(t[id].l>r || t[id].r<l)
	{
		return;
	}
	if(t[id].l>=l && t[id].r<=r)
	{
		if(op==0 || op==1)
		{
			int tmp=(t[id].r-t[id].l+1);
			t[id].val=op;
			t[id].maxl=t[id].maxr=t[id].maxx=t[id].sum=tmp*t[id].val;
    		t[id].Imaxl=t[id].Imaxr=t[id].Imaxx=t[id].sum=tmp*(t[id].val^1);
		}
		else if(op==2)
		{
			if(t[id].val==2)
			{
				change(id);
				t[id].val=-1;//两次当成未进行过 
			}
			else if(t[id].val<=1 && t[id].val>=0)
			{
				int tmp=(t[id].r-t[id].l+1);
				t[id].val^=1; 
				t[id].maxl=t[id].maxr=t[id].maxx=t[id].sum=tmp*t[id].val;
                t[id].Imaxl=t[id].Imaxr=t[id].Imaxx=tmp*(t[id].val^1);
			}
			else if(t[id].val=-1)
			{
				change(id);
				t[id].val=2;
			}
		}
		return;
	}
	if(t[id].val>=0)
	{
		downdate(id);
	}
	update(id*2,l,r,op);
	update(id*2+1,l,r,op);
	pushup(id);
}

int findsum(int id,int l,int r)
{
	if(t[id].l>r || t[id].r<l)
	{
		return 0;
	}
	if(t[id].l>=l&&t[id].r<=r)
	{
		return t[id].sum;
	}
    if(t[id].val>=0)
    {
    	downdate(id);
	}
    int res=findsum(id*2,l,r)+findsum(id*2+1,l,r);
    return res;
}

void findmaxx(int id,int l,int r)
{
	if(t[id].l>r||t[id].r<l)
	{
		return;
	}
    if(t[id].l>=l&&t[id].r<=r)
    {
        ans=max(ans,max(t[id].maxx,pre+t[id].maxl));
        if(t[id].sum==t[id].r-t[id].l+1)
		{
			pre+=t[id].sum;
		 } 
		else
		{
		 	pre=t[id].maxr;
		}
        return;
    }
    if(t[id].val>=0)
	{
		downdate(id);
	}
    findmaxx(id*2,l,r);
	findmaxx(id*2+1,l,r);
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int op,x,y;
		cin>>op>>x>>y;
		x++,y++;
		if(op==1 || op==2 || op==0)
		{
			update(1,x,y,op);
		}
		else if(op==3)
		{
			cout<<findsum(1,x,y)<<endl;
		}
		else
		{
			ans=pre=0;
			findmaxx(1,x,y);
			cout<<ans<<endl;
		}
	}
	return 0;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...