求调

P2572 [SCOI2010] 序列操作

Eous @ 2024-07-18 09:01:17

#include<bits/stdc++.h>
using namespace std;
int const maxn=1e5+10;
struct node{
    int l,r,cnt[2],sum[2],suml[2],sumr[2];
    bool lazy[3];
    /*
    cnt[0]表示0的个数,cnt[1]表示1的个数
    sum[0]表示最多的连续的0的个数,sum[1]表述最多的连续的1的个数
    suml[0]表示从左边界开始数的0的个数
    sumr[0]表示从左边界开始数的0的个数
    lazy[0]表示全部取0,lazy[1]表示全部取1,lazy[2]表示全部取反
    */
}tree[maxn<<2];
int n,m;
int op,l,r;
void push_up(node &rt,node &ls,node &rs)
{
    rt.cnt[0]=ls.cnt[0]+rs.cnt[0];
    rt.cnt[1]=ls.cnt[1]+rs.cnt[1];
    rt.sum[0]=max(ls.sumr[0]+rs.suml[0],max(ls.sum[0],rs.sum[0]));
    rt.sum[1]=max(ls.sumr[1]+rs.suml[1],max(ls.sum[1],rs.sum[1]));
    if(ls.cnt[0]==ls.r-ls.l+1)
        rt.suml[0]=ls.r-ls.l+1+rs.suml[0];
    else
        rt.suml[0]=ls.suml[0];
    if(ls.cnt[1]==ls.r-ls.l+1)
        rt.suml[1]=ls.r-ls.l+1+rs.suml[1];
    else
        rt.suml[1]=ls.suml[1];
    if(rs.cnt[0]==rs.r-rs.l+1)
        rt.sumr[0]=rs.r-rs.l+1+ls.sumr[0];
    else
        rt.sumr[0]=rs.sumr[0];
    if(rs.cnt[1]==rs.r-rs.l+1)
        rt.sumr[1]=rs.r-rs.l+1+ls.sumr[1];
    else
        rt.sumr[1]=rs.sumr[1];
}
void push_down(int rt)
{
    int len=tree[rt].r-tree[rt].l+1;
    if(tree[rt].lazy[0])
    {
        tree[rt<<1].cnt[1]=tree[rt<<1].sum[1]=tree[rt<<1].suml[1]=tree[rt<<1].sumr[1]=0;
        tree[rt<<1|1].cnt[1]=tree[rt<<1|1].sum[1]=tree[rt<<1|1].suml[1]=tree[rt<<1|1].sumr[1]=0;
        tree[rt<<1].cnt[0]=tree[rt<<1].sum[0]=tree[rt<<1].suml[0]=tree[rt<<1].sumr[0]=len>>1;
        tree[rt<<1|1].cnt[0]=tree[rt<<1|1].sum[0]=tree[rt<<1|1].suml[0]=tree[rt<<1|1].sumr[0]=len-(len>>1);
        tree[rt<<1].lazy[0]=tree[rt<<1|1].lazy[0]=1;
        tree[rt].lazy[0]=0;
    }
    if(tree[rt].lazy[1])
    {
        tree[rt<<1].cnt[0]=tree[rt<<1].sum[0]=tree[rt<<1].suml[0]=tree[rt<<1].sumr[0]=0;
        tree[rt<<1|1].cnt[0]=tree[rt<<1|1].sum[0]=tree[rt<<1|1].suml[0]=tree[rt<<1|1].sumr[0]=0;
        tree[rt<<1].cnt[1]=tree[rt<<1].sum[1]=tree[rt<<1].suml[1]=tree[rt<<1].sumr[1]=len>>1;
        tree[rt<<1|1].cnt[1]=tree[rt<<1|1].sum[1]=tree[rt<<1|1].suml[1]=tree[rt<<1|1].sumr[1]=len-(len>>1);
        tree[rt<<1].lazy[1]=tree[rt<<1|1].lazy[1]=1;
        tree[rt].lazy[1]=0;
    }
    if(tree[rt].lazy[2])
    {
        swap(tree[rt<<1].cnt[0],tree[rt<<1].cnt[1]);
        swap(tree[rt<<1].sum[0],tree[rt<<1].sum[1]);
        swap(tree[rt<<1].suml[0],tree[rt<<1].suml[1]);
        swap(tree[rt<<1].sumr[0],tree[rt<<1].sumr[1]);
        swap(tree[rt<<1|1].cnt[0],tree[rt<<1|1].cnt[1]);
        swap(tree[rt<<1|1].sum[0],tree[rt<<1|1].sum[1]);
        swap(tree[rt<<1|1].suml[0],tree[rt<<1|1].suml[1]);
        swap(tree[rt<<1|1].sumr[0],tree[rt<<1|1].sumr[1]);
        tree[rt<<1].lazy[2]=tree[rt<<1|1].lazy[2]=1;
        tree[rt].lazy[2]=0;
    }
}
void build(int l,int r,int rt)
{
    tree[rt].l=l;
    tree[rt].r=r;
    if(l==r)
    {
        int tmp;
        cin>>tmp;
        tree[rt].cnt[0]=tree[rt].sum[0]=tree[rt].suml[0]=tree[rt].sumr[0]=(!tmp);
        tree[rt].cnt[1]=tree[rt].sum[1]=tree[rt].suml[1]=tree[rt].sumr[1]=tmp;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    push_up(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
void print(int rt)
{
    int l=tree[rt].l;
    int r=tree[rt].r; 
    if(l==r)
    {
        printf("%d ",tree[rt].cnt[1]);
        return;
    }
    push_down(rt);
    print(rt<<1);
    print(rt<<1|1);
}
void update0(int ql,int qr,int rt)
{
    int l=tree[rt].l;
    int r=tree[rt].r;
    if(ql<=l&&r<=qr)
    {
        tree[rt].lazy[1]=tree[rt].lazy[2]=0;
        tree[rt].lazy[0]=1;
        tree[rt].cnt[0]=tree[rt].sum[0]=tree[rt].suml[0]=tree[rt].sumr[0]=r-l+1;
        tree[rt].cnt[1]=tree[rt].sum[1]=tree[rt].suml[1]=tree[rt].sumr[1]=0;
        return;
    }
    push_down(rt);
    int mid=(l+r)>>1;
    if(ql<=mid)
        update0(ql,qr,rt<<1);
    if(qr>mid)
        update0(ql,qr,rt<<1|1);
    push_up(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
void update1(int ql,int qr,int rt)
{
    int l=tree[rt].l;
    int r=tree[rt].r;
    if(ql<=l&&r<=qr)
    {
        tree[rt].lazy[0]=tree[rt].lazy[2]=0;
        tree[rt].lazy[1]=1;
        tree[rt].cnt[1]=tree[rt].sum[1]=tree[rt].suml[1]=tree[rt].sumr[1]=r-l+1;
        tree[rt].cnt[0]=tree[rt].sum[0]=tree[rt].suml[0]=tree[rt].sumr[0]=0;
        return;
    }
    push_down(rt);
    int mid=(l+r)>>1;
    if(ql<=mid)
        update1(ql,qr,rt<<1);
    if(qr>mid)
        update1(ql,qr,rt<<1|1);
    push_up(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
void update2(int ql,int qr,int rt)
{
    int l=tree[rt].l;
    int r=tree[rt].r;
    if(ql<=l&&r<=qr)
    {
        tree[rt].lazy[2]=1;
        swap(tree[rt].cnt[0],tree[rt].cnt[1]);
        swap(tree[rt].sum[0],tree[rt].sum[1]);
        swap(tree[rt].suml[0],tree[rt].suml[1]);
        swap(tree[rt].sumr[0],tree[rt].sumr[1]);
        return;
    }
    push_down(rt);
    int mid=(l+r)>>1;
    if(ql<=mid)
        update2(ql,qr,rt<<1);
    if(qr>mid)
        update2(ql,qr,rt<<1|1);
    push_up(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
int query1(int ql,int qr,int rt)//查1的个数
{
    int l=tree[rt].l;
    int r=tree[rt].r;
    if(ql<=l&&r<=qr)
        return tree[rt].cnt[1];
    push_down(rt);
    int mid=(l+r)>>1,ret=0;
    if(ql<=mid)
        ret+=query1(ql,qr,rt<<1);
    if(qr>mid)
        ret+=query1(ql,qr,rt<<1|1);
    return ret;
}
node query2(int ql,int qr,int rt)
{
    int l=tree[rt].l;
    int r=tree[rt].r;
    if(ql<=l&&r<=qr)
        return tree[rt];
    push_down(rt);
    int mid=(l+r)>>1;
    if(ql<=mid&&mid<qr)
    {
        node x=query2(ql,qr,rt<<1),y=query2(ql,qr,rt<<1|1),ret;
        push_up(ret,x,y);
        ret.l=x.l,ret.r=y.r;
        return ret;
    }
    else if(ql<=mid)
        return query2(ql,qr,rt<<1);
    else if(qr>mid)
        return query2(ql,qr,rt<<1|1);
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    build(1,n,1);
    while(m--)
    {
        cin>>op>>l>>r;
        l++,r++;
        switch(op) 
        {
            case 0:
                update0(l,r,1);
                break;
            case 1:
                update1(l,r,1);
                break;
            case 2:
                update2(l,r,1);
                break;
            case 3:
                cout<<query1(l,r,1)<<endl;
                break;
            case 4:
                cout<<query2(l,r,1).sum[1]<<endl;
                break;
        }
        print(1);
        cout<<endl;
    }
    return 0;
}

by Eous @ 2024-07-18 09:22:26

print()函数是调试代码,不管他


|