线段树WA求调,玄关!

P2572 [SCOI2010] 序列操作

zhangxiao666 @ 2024-07-25 19:37:31

#include <bits/stdc++.h>
#define ls x << 1
#define rs x << 1 | 1
#define lson ls, l, mid
#define rson rs, mid + 1, r
using namespace std;
const int N = 1e5 + 10;
int n, m;
array<int, N> a;

struct stu
{
    int sum0, sum1;
    int max0, max1;
    int l0, l1, r0, r1;
    int tag1, tag2;
};

array<stu, N << 2> tr;
stu t;

void PushUp(int x)
{
    tr[x].sum0 = tr[ls].sum0 + tr[rs].sum0;
    tr[x].sum1 = tr[ls].sum1 + tr[rs].sum1;
    tr[x].max0 = max(max(tr[ls].max0, tr[rs].max0), tr[ls].r0 + tr[rs].l0);
    tr[x].max1 = max(max(tr[ls].max1, tr[rs].max1), tr[ls].r1 + tr[rs].l1); 
    tr[x].l0 = tr[ls].sum1 ? tr[ls].sum0 + tr[rs].l0 : tr[ls].l0;
    tr[x].l1 = tr[ls].sum0 ? tr[ls].sum1 + tr[rs].l1 : tr[ls].l1;    
    tr[x].r0 = tr[rs].sum1 ? tr[rs].sum0 + tr[ls].r0 : tr[rs].r0;
    tr[x].r1 = tr[rs].sum0 ? tr[rs].sum1 + tr[ls].r1 : tr[rs].r1;   
}

stu Merge(stu aa, stu bb)
{
    stu xx;
    xx.sum0 = aa.sum0 + bb.sum0;
    xx.sum1 = aa.sum1 + bb.sum1;
    xx.max0 = max(max(aa.max0, bb.max0), aa.r0 + bb.l0);
    xx.max1 = max(max(aa.max1, bb.max1), aa.r1 + bb.l1);    
    xx.l0 = !aa.sum1 ? aa.sum0 + bb.l0 : aa.l0;
    xx.l1 = !aa.sum0 ? aa.sum1 + bb.l1 : aa.l1;  
    xx.r0 = !bb.sum1 ? bb.sum0 + aa.r0 : bb.r0;
    xx.r1 = !bb.sum0 ? bb.sum1 + aa.r1 : bb.r1; 
    return xx;
}

void Build(int x, int l, int r)
{
    tr[x].tag1 = -1;
    if (l == r) 
    {
        if (a[l] == 0)
            tr[x].sum0 = tr[x].max0 = tr[x].l0 = tr[x].r0 = 1;
        else
            tr[x].sum1 = tr[x].max1 = tr[x].l1 = tr[x].r1 = 1;
        return;
    }
    int mid = l + r >> 1;
    Build(lson), Build(rson);
    PushUp(x);
}

void Change1(int x, int l, int r, int k)
{
    if (k == 0)
    {
        tr[x].sum0 = (r - l + 1), tr[x].sum1 = 0;
        tr[x].max0 = (r - l + 1), tr[x].max1 = 0;
        tr[x].l0 = tr[x].r0 = (r - l + 1);
        tr[x].l1 = tr[x].r1 = 0;
    }
    if (k == 1)
    {
        tr[x].sum1 = (r - l + 1), tr[x].sum0 = 0;
        tr[x].max1 = (r - l + 1), tr[x].max0 = 0;
        tr[x].l1 = tr[x].r1 = (r - l + 1);
        tr[x].l0 = tr[x].r0 = 0;    
    }
    tr[x].tag1 = k; tr[x].tag2 = 0;
}

void Change2(int x, int l, int r)
{
    swap(tr[x].sum0, tr[x].sum1);
    swap(tr[x].max0, tr[x].max1);
    swap(tr[x].l0, tr[x].l1);
    swap(tr[x].r0, tr[x].r1);
    if (tr[x].tag1 != -1) tr[x].tag1 ^= 1;
    else tr[x].tag2 ^= 1;
}

void PushDown(int x, int l, int r)
{
    int mid = l + r >> 1;
    if (tr[x].tag1 != -1)
    {
        Change1(lson, tr[x].tag1);
        Change1(rson, tr[x].tag1);
        tr[x].tag1 = -1;
    }
    if (tr[x].tag2)
    {
        Change2(lson), Change2(rson);
        tr[x].tag2 = 0;
    }
}

void Update(int x, int l, int r, int ql, int qr, int op)
{
    if (ql <= l && r <= qr)
    {
        if (op == 0) Change1(x, l, r, 0);
        if (op == 1) Change1(x, l, r, 1);
        if (op == 2) Change2(x, l, r);      
        return;
    }
    int mid = l + r >> 1; PushDown(x, l, r);
    if (ql <= mid) Update(lson, ql, qr, op);
    if (qr > mid) Update(rson, ql, qr, op);
    PushUp(x);
}

int Query1(int x, int l, int r, int ql, int qr)
{
    if (ql <= l && r <= qr) return tr[x].sum1;
    int mid = l + r >> 1, res = 0; PushDown(x, l, r);
    if (ql <= mid) res += Query1(lson, ql, qr);
    if (qr > mid) res += Query1(rson, ql, qr);
    return res;
}

stu Query2(int x, int l, int r, int ql, int qr)
{
    if (ql <= l && r <= qr) return tr[x];
    PushDown(x, l, r);
    int mid = l + r >> 1;
    if (qr <= mid) return Query2(lson, ql, qr);
    if (ql > mid) return Query2(rson, ql, qr);
    return Merge(Query2(lson, ql, qr), Query2(rson, ql, qr));
}

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> a[i];
    Build(1, 1, n);
    while (m--)
    {
        int op, l, r;
        cin >> op >> l >> r;
        l++, r++;
        if (op < 3) 
            Update(1, 1, n, l, r, op);
        else
        {
            if (op == 3)
                cout << Query1(1, 1, n, l, r) << "\n";
            else 
            {
                cout << Query2(1, 1, n, l, r).max1 << "\n";
            }
        }
    }
    return 0;
}

by pugong @ 2024-08-09 21:32:14

@zhangxiao666 给你组数据
输入:

5 5
0 1 1 1 1 
4 0 3
1 1 2
3 0 0
0 4 4
1 1 3

输出:

3
0

by zhangxiao666 @ 2024-08-10 11:03:29

@pugong 已过,拜谢%%%


|