求助(调了两天了1qwq

P2572 [SCOI2010] 序列操作

Acestar @ 2020-02-12 23:13:59

样例过了,WA :-(

线段树题,写法每个人的都有差异,望各位dalaojuruo看看

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>

using namespace std;

const int N = 1e5+10;

int a[N];
int sum[N<<2],maxs[N<<2][2],lmax[N<<2][2],rmax[N<<2][2];
//sum[i]: 以i为根的子树的叶节点中1的个数。
//maxs[i][0/1]: 以i为根的子树的叶节点中连续的0/1的个数。
//lmax[i][0/1]: 以i为根的子树的叶节点中从左开始连续的0/1的个数。
//rmax[i][0/1]: 以i为根的子树的叶节点中从右开始连续的0/1的个数。 
int tag[N<<2],rev[N<<2],len[N<<2];
//tag[i]=-1/0/1 (lazytag): -1表示没有赋值,0表示赋值为0,1表示赋值为1。
//rev[i]=0/1 (reverse): 0表示没有反转,1表示反转。 
//len[i]: 以i为根的子树的叶节点个数。

int read()
{
    int x=0;
    char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x;
}

void pushup(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];

    lmax[rt][1]=(maxs[rt<<1][1]==len[rt<<1])?len[rt<<1]+lmax[rt<<1|1][1]:lmax[rt<<1][1];
    lmax[rt][0]=(maxs[rt<<1][0]==len[rt<<1])?len[rt<<1]+lmax[rt<<1|1][0]:lmax[rt<<1][0];

    rmax[rt][1]=(maxs[rt<<1|1][1]==len[rt<<1|1])?len[rt<<1|1]+rmax[rt<<1][1]:rmax[rt<<1|1][1];
    rmax[rt][0]=(maxs[rt<<1|1][0]==len[rt<<1|1])?len[rt<<1|1]+rmax[rt<<1][0]:rmax[rt<<1|1][0];

    maxs[rt][1]=max(max(lmax[rt<<1][1],rmax[rt<<1|1][1]),rmax[rt<<1][1]+lmax[rt<<1|1][1]);
    maxs[rt][0]=max(max(lmax[rt<<1][0],rmax[rt<<1|1][0]),rmax[rt<<1][0]+lmax[rt<<1|1][0]);
}

void build(int l,int r,int rt)
{
    tag[rt]=-1;
    len[rt]=r-l+1;
    if(l==r)
    {
        sum[rt]=a[l];
        lmax[rt][1]=rmax[rt][1]=maxs[rt][1]=a[l];
        lmax[rt][0]=rmax[rt][0]=maxs[rt][0]=a[l]^1;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    pushup(rt);
}

void pushdown(int rt)
{
    if(tag[rt]!=-1)
    {
        sum[rt<<1]=lmax[rt<<1][1]=rmax[rt<<1][1]=maxs[rt<<1][1]=tag[rt]*len[rt<<1];
        sum[rt<<1|1]=lmax[rt<<1|1][1]=rmax[rt<<1|1][1]=maxs[rt<<1|1][1]=tag[rt]*len[rt<<1|1];
        lmax[rt<<1][0]=rmax[rt<<1][0]=maxs[rt<<1][0]=len[rt<<1]-sum[rt<<1];
        lmax[rt<<1|1][0]=rmax[rt<<1|1][0]=maxs[rt<<1|1][0]=len[rt<<1|1]-sum[rt<<1|1];
        tag[rt<<1]=tag[rt<<1|1]=tag[rt];
        rev[rt]=rev[rt<<1]=rev[rt<<1|1]=0;
        tag[rt]=-1;
    }
    if(rev[rt])
    {
        sum[rt<<1]=len[rt<<1]-sum[rt<<1];
        swap(maxs[rt<<1][1],maxs[rt<<1][0]);
        swap(lmax[rt<<1][1],lmax[rt<<1][0]);
        swap(rmax[rt<<1][1],rmax[rt<<1][0]);
        if(tag[rt<<1]!=-1) tag[rt<<1]^=1;
        else rev[rt<<1]^=1;
        sum[rt<<1|1]=len[rt<<1|1]-sum[rt<<1|1];
        swap(maxs[rt<<1|1][1],maxs[rt<<1|1][0]);
        swap(lmax[rt<<1|1][1],lmax[rt<<1|1][0]);
        swap(rmax[rt<<1|1][1],rmax[rt<<1|1][0]);
        if(tag[rt<<1|1]!=-1) tag[rt<<1|1]^=1;
        else rev[rt<<1|1]^=1;
        rev[rt]=0;
    }
}

void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        if(c<=1)
        {
            sum[rt]=c*len[rt];
            lmax[rt][1]=rmax[rt][1]=maxs[rt][1]=c*len[rt];
            lmax[rt][0]=rmax[rt][0]=maxs[rt][0]=len[rt]-sum[rt];
            tag[rt]=c;
            rev[rt]=0;
        }
        else
        {
            sum[rt]=len[rt]-sum[rt];
            swap(maxs[rt][1],maxs[rt][0]);
            swap(lmax[rt][1],lmax[rt][0]);
            swap(rmax[rt][1],rmax[rt][0]);
            rev[rt]^=1;
        }
        return;
    }
    pushdown(rt);
    int mid=(l+r)>>1;
    if(L<=mid) update(L,R,c,l,mid,rt<<1);
    if(mid<R) update(L,R,c,mid+1,r,rt<<1|1);
    pushup(rt);
}

int qry_sum(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R) return sum[rt];
    pushdown(rt);
    int ret=0;
    int mid=(l+r)>>1;
    if(L<=mid) ret+=qry_sum(L,R,l,mid,rt<<1);
    if(mid<R) ret+=qry_sum(L,R,mid+1,r,rt<<1|1);
    return ret;
}

int qry_max(int L,int R,int l,int r,int rt)
{
    if(L==l&&r==R) return maxs[rt][1];
    pushdown(rt);
    int mid=(l+r)>>1;
    if(R<=mid) return qry_max(L,R,l,mid,rt<<1);
    else if(mid<L) return qry_max(L,R,mid+1,r,rt<<1|1);
    else return max(max(qry_max(L,mid,l,mid,rt<<1),qry_max(mid+1,R,mid+1,r,rt<<1|1)),
                    min(rmax[rt<<1][1],mid-L+1)+min(lmax[rt<<1|1][1],R-mid));
}

int main()
{
    int n=read(),m=read();
    for(int i=1; i<=n; i++) a[i]=read();
    build(1,n,1);
    while(m--)
    {
        int t=read(),l=read()+1,r=read()+1;
        if(t<=2) update(l,r,t,1,n,1);
        else if(t==3) printf("%d\n",qry_sum(l,r,1,n,1));
        else printf("%d\n",qry_max(l,r,1,n,1));
    }
    return 0;
}

by Thomas_ @ 2020-02-12 23:14:15

现在都在关心名字


by Andysun06 @ 2020-02-12 23:21:28

我不是大佬,不能看


by 览遍千秋 @ 2020-02-13 07:08:43

为啥不写珂朵莉树呢


by Acestar @ 2020-02-13 07:57:34

@expect 原因很简单——我太菜了,不会qwq


|