10pts 线段树,翻讨论区好像没翻到 Hack
查看原帖
10pts 线段树,翻讨论区好像没翻到 Hack
809729
SJZ2010楼主2023/11/24 18:17

只过了 Hack 和 #2

#include <tuple>
#include <cstdio>
#include <algorithm>

#define lson(now) (now << 1)
#define rson(now) (now << 1 | 1)

const int N = 1e5 + 5;

int n, m;
int a[N];

struct Segment_Tree
{
    int cov[N << 2], rev[N << 2];
    int sum[N << 2], suf[N << 2], sub[N << 2], pre[N << 2];
    int sub0[N << 2], pre0[N << 2], suf0[N << 2];

    void cover(int now, int s, int t, bool val)
    {
        if (val == 1)
        {
            sum[now] = sub[now] = suf[now] = pre[now] = t - s + 1;
            sub0[now] = suf0[now] = pre0[now] = 0;
        }
        else
        {
            sum[now] = sub[now] = suf[now] = pre[now] = 0;
            sub0[now] = suf0[now] = pre0[now] = t - s + 1;
        }
    }
    void reverse(int now, int s, int t)
    {
        sum[now] = (t - s + 1) - sum[now];
        std::swap(sub[now], sub0[now]);
        std::swap(pre[now], pre0[now]);
        std::swap(suf[now], suf0[now]);
    }

    void pushup(int now, int s, int t)
    {
        int mid = (s + t) >> 1;
        sum[now] = sum[lson(now)] + sum[rson(now)];
        sub[now] = std::max({sub[lson(now)], 
                            sub[rson(now)], 
                            suf[lson(now)] + pre[rson(now)]});
        suf[now] = sum[rson(now)] == (t - mid) ? 
                   suf[lson(now)] + t - mid :
                   suf[rson(now)];
        pre[now] = sum[lson(now)] == (mid - s + 1) ? 
                   mid - s + 1 + pre[rson(now)] : 
                   pre[lson(now)];
        
        sub0[now] = std::max({sub0[lson(now)], 
                              sub0[rson(now)], 
                              suf0[lson(now)] + pre0[rson(now)]});
        suf0[now] = sum[rson(now)] ? 
                    suf0[rson(now)] : 
                    (t - mid) + suf0[lson(now)];
        pre0[now] = sum[lson(now)] ? 
                    pre0[lson(now)] : 
                    (mid - s + 1) + pre0[rson(now)];
    }
    void pushdown(int now, int s, int t)
    {
        int mid = (s + t) >> 1;
        if (cov[now] != -1)
        {
            cover(lson(now), s, mid, cov[now]);
            cover(rson(now), mid + 1, t, cov[now]);
            cov[lson(now)] = cov[rson(now)] = cov[now];
            rev[lson(now)] = rev[rson(now)] = 0;
            cov[now] = -1;
        }
        if (rev[now])
        {
            reverse(lson(now), s, mid);
            reverse(rson(now), mid + 1, t);
            rev[lson(now)] ^= 1;
            rev[rson(now)] ^= 1;
            //if (rev[lson(now)])
            //    cov[lson(now)] ^= 1;
            //if (rev[rson(now)])
            //    cov[rson(now)] ^= 1;
            rev[now] = 0;
        }
    }

    void build(int s, int t, int now)
    {
        cov[now] = -1;
        if (s == t)
        {
            sum[now] = sub[now] = pre[now] = suf[now] = a[s];
            sub0[now] = pre0[now] = suf0[now] = !a[s];
            return;
        }
        int mid = (s + t) >> 1;
        build(s, mid, lson(now));
        build(mid + 1, t, rson(now));
        pushup(now, s, t);
    }
    void modify_cov(int l, int r, int s, int t, int now, bool val)
    {
        if (l <= s && t <= r)
        {
            cov[now] = val;
            cover(now, s, t, val);
            return;
        }
        int mid = (s + t) >> 1;
        pushdown(now, s, t);
        if (mid >= l)
            modify_cov(l, r, s, mid, lson(now), val);
        if (mid < r)
            modify_cov(l, r, mid + 1, t, rson(now), val);
        pushup(now, s, t);
    }
    void modify_rev(int l, int r, int s, int t, int now)
    {
        if (l <= s && t <= r)
        {
            rev[now] ^= 1;
            reverse(now, s, t);
            return;
        }
        int mid = (s + t) >> 1;
        pushdown(now, s, t);
        if (mid >= l)
            modify_rev(l, r, s, mid, lson(now));
        if (mid < r)
            modify_rev(l, r, mid + 1, t, rson(now));
        pushup(now, s, t);
    }
    int query_sum(int l, int r, int s, int t, int now)
    {
        if (l <= s && t <= r)
            return sum[now];
        int mid = (s + t) >> 1, res(0);
        pushdown(now, s, t);
        if (mid >= l)
            res += query_sum(l, r, s, mid, lson(now));
        if (mid < r)
            res += query_sum(l, r, mid + 1, t, rson(now));
        pushup(now, s, t);
        return res;
    }
    std::tuple < int, int, int, int >
    query_sub(int l, int r, int s, int t, int now)
    {
        //printf("%d: %d %d %d %d\n", now, pre[now], sub[now], suf[now], sum[now]);
        if (l <= s && t <= r)
            return std::make_tuple(pre[now], sub[now], suf[now], sum[now]);
        int mid = (s + t) >> 1;
        int sb, pr, sf, sm, _sb, _pr, _sf, _sm;
        std::tuple < int, int, int, int > tp;
        pushdown(now, s, t);
        if (mid >= l)
        {
            if (mid < r)
            {
                tp = query_sub(l, r, s, mid, lson(now));
                sb = std::get < 1 > (tp);
                pr = std::get < 0 > (tp);
                sf = std::get < 2 > (tp);
                sm = std::get < 3 > (tp);
                tp = query_sub(l, r, mid + 1, t, rson(now));
                _sb = std::get < 1 > (tp);
                _pr = std::get < 0 > (tp);
                _sf = std::get < 2 > (tp);
                _sm = std::get < 3 > (tp);
                sb = std::max({sb, _sb, sf + _pr});
                sb = std::max({sb, _sb, sf + _pr});
                pr = sm == (mid - s + 1) ? sm + _pr : pr;
                sf = _sm == (t - mid) ? _sm + sf : _sf;
                sm = sm + _sm;
                pushup(now, s, t);
                return std::make_tuple(pr, sb, sf, sm);
            }
            tp = query_sub(l, r, s, mid, lson(now));
            pushup(now, s, t);
            return tp;
        }
        tp = query_sub(l, r, mid + 1, t, rson(now));
        pushup(now, s, t);
        return tp;
    }
    
    void dfs(int s, int t, int now)
    {
        if (s == t)
        {
            printf("%d ", sum[now]);
            return;
        }
        int mid = (s + t) >> 1;
        pushdown(now, s, t);
        dfs(s, mid, lson(now));
        dfs(mid + 1, t, rson(now));
        pushup(now, s, t);
    }
}
SegT;

int opt, l, r;

int main()
{
    scanf("%d %d", &n, &m);
    int i;
    for (i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    SegT.build(1, n, 1);
    while (m--)
    {
        scanf("%d %d %d", &opt, &l, &r);
        l++, r++;
        if (opt == 0)
            SegT.modify_cov(l, r, 1, n, 1, 0);
        else if (opt == 1)
            SegT.modify_cov(l, r, 1, n, 1, 1);
        else if (opt == 2)
            SegT.modify_rev(l, r, 1, n, 1);
        else if (opt == 3)
            printf("%d\n", SegT.query_sum(l, r, 1, n, 1));
        else if (opt == 4)
            printf("%d\n", std::get < 1 > (SegT.query_sub(l, r, 1, n, 1)));
    }
    return 0;
}
2023/11/24 18:17
加载中...