帮一个MnZn问题

P2572 [SCOI2010] 序列操作

YeshengGZM @ 2023-10-12 20:06:44

#include<bits/stdc++.h>
#define lo (nw<<1)
#define ro (nw<<1|1)
#define md ((l+r)>>1)
#define int long long
using namespace std;

const int N=100010,INF=0x7fffffffffffffff;

int n,m;
int a[N];

struct node
{
    int tr,sz;
    int sm1,sm2;
    int fr1,fr2;
    int re1,re2;
    int c1,c2;
}t[N << 2];

struct segment_tree
{
    void upd(int nw)
    {
        t[nw].sz=t[lo].sz+t[ro].sz;
        t[nw].tr=t[lo].tr+t[ro].tr;
        t[nw].sm1=max(t[lo].re1+t[ro].fr1,max(t[lo].sm1,t[ro].sm1));
        if(t[lo].fr1==t[lo].sz)
            t[nw].fr1=t[lo].fr1+t[ro].fr1;
        else
            t[nw].fr1=t[lo].fr1;
        if(t[ro].re1==t[ro].sz)
            t[nw].re1=t[ro].re1+t[lo].re1;
        else
            t[nw].re1=t[ro].re1;
        t[nw].sm2=max(t[lo].re2+t[ro].fr2,max(t[lo].sm2,t[ro].sm2));
        if(t[lo].fr2==t[lo].sz)
            t[nw].fr2=t[lo].fr2+t[ro].fr2;
        else
            t[nw].fr2=t[lo].fr2;
        if(t[ro].re2==t[ro].sz)
            t[nw].re2=t[ro].re2+t[lo].re2;
        else
            t[nw].re2=t[ro].re2;
        return ;
    }
    void mkc1(int nw,int z)
    {
        t[nw].c1=z;
        t[nw].tr=z*t[nw].sz;
        t[nw].sm1=z*t[nw].sz;
        t[nw].fr1=z*t[nw].sz;
        t[nw].re1=z*t[nw].sz;
        t[nw].sm2=(z^1)*t[nw].sz;
        t[nw].fr2=(z^1)*t[nw].sz;
        t[nw].re2=(z^1)*t[nw].sz;
        t[nw].c2=0;
        return ;
    }
    void mkc2(int nw)
    {
        t[nw].c2^=1;
        t[nw].tr=t[nw].sz-t[nw].tr;
        swap(t[nw].sm1,t[nw].sm2);
        swap(t[nw].fr1,t[nw].fr2);
        swap(t[nw].re1,t[nw].re2);
        return ;
    }
    void psd(int nw)
    {
        if(t[nw].c1!=-1)
        {
            mkc1(lo,t[nw].c1);
            mkc1(ro,t[nw].c1);
            t[nw].c1=-1;
        }
        if(t[nw].c2!=0)
        {
            mkc2(lo);
            mkc2(ro);
            t[nw].c2=0;
        }
        return ;
    }
    void bld(int nw,int l,int r)
    {
        t[nw].c1=-1;
        t[nw].c2=0;
        if(l==r)
        {
            t[nw].tr=a[l];
            t[nw].sz=1;
            t[nw].sm1=a[l];
            t[nw].fr1=a[l];
            t[nw].re1=a[l];
            t[nw].sm2=a[l]^1;
            t[nw].fr2=a[l]^1;
            t[nw].re2=a[l]^1;
            return ;
        }
        bld(lo,l,md);
        bld(ro,md+1,r);
        upd(nw);
        return ;
    }
    void atr(int nw,int l,int r,int x,int y,int z)
    {
        psd(nw);
        if(x<=l&&r<=y)
        {
            mkc1(nw,z);
            return ;
        }

        if(x<=md)
            atr(lo,l,md,x,y,z);
        if(y>md)
            atr(ro,md+1,r,x,y,z);
        upd(nw);
        return ;
    }
    void atc(int nw,int l,int r,int x,int y)
    {
        psd(nw);
        if(x<=l&&r<=y)
        {
            mkc2(nw);
            return ;
        }

        if(x<=md)
            atc(lo,l,md,x,y);
        if(y>md)
            atc(ro,md+1,r,x,y);
        upd(nw);
        return ;
    }
    int qrt(int nw,int l,int r,int x,int y)
    {
        if(x<=l&&r<=y)
            return t[nw].tr;
        psd(nw);
        int sm=0;
        if(x<=md)
            sm=sm+qrt(lo,l,md,x,y);
        if(y>md)
            sm=sm+qrt(ro,md+1,r,x,y);
        return sm;
    }
    int qry(int nw,int l,int r,int x,int y)
    {
        if(x<=l&&r<=y)
            return t[nw].sm1;
        psd(nw);
        int sm=-INF;
        if(x<=md)
            sm=max(sm, qry(lo,l,md,x,y));
        if(y>md)
            sm=max(sm, qry(ro,md+1,r,x,y));
        return sm;
    }
}ST;

signed main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    ST.bld(1,1,n);
    for(int i=1;i<=m;i++)
    {
        int op,x,y;
        cin>>op>>x>>y;
        ++x; ++y;
        if(op==0||op==1)
        {
            ST.atr(1,1,n,x,y,op);
        }
        if(op==2)
        {
            ST.atc(1,1,n,x,y);
        }
        if(op==3)
        {
            cout<<ST.qrt(1,1,n,x,y)<<'\n';
        }
        if(op==4)
        {
            cout<<ST.qry(1,1,n,x,y)<<'\n';
        }
    }
    return 0;
}

by CoderXL @ 2023-10-18 13:54:06

这些数据,可以手模一下,看看程序哪里逻辑有问题。 其余的,你这个线段树写法我不熟悉,不敢瞎说,不过修改函数第一行是不是应该加上这个?

if(y<l||r<x)return;

无所谓,先看样例吧

输入#1

3 1
1 1 1 
4 1 2

输出#1

2

输入#2

13 12
0 0 1 1 1 0 1 1 0 0 1 1 0 
3 3 3
1 1 1
0 3 6
4 2 3
3 6 8
1 0 9
0 6 12
0 4 6
1 2 11
3 5 7
3 1 9
4 9 11

输出#2

1
1
1
3
9
3

|