• 线段树 区间合并 F


    F - Sequence operation



    题解:
    这个题目不是一个特别难的题目,但是呢,写了好久,首先线段树难敲,其次就是bug难找,最后这个代码都被我改的乱七八糟的了,
    这个有两个地方要注意一下,一个是取反的lazy标志,每次取反都是对1取异或,还有一个也是这个取反的lazy标志,
    这个标志再第一种操作之后要进行消除。


    #include <cstdio>
    #include <cstdlib>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <stack>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn = 1e6 + 100;
    struct node
    {
        int sum;
        int max_sub, max_zero;
        int l, r, len;
        int lazy1, lazy2;
        int max_prezero, max_lastzero;
        int max_preone, max_lastone;
    }tree[maxn * 4];
    int a[maxn];
    
    void push_up(int id)
    {
        tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum;
    
        tree[id].max_preone = tree[id << 1].max_preone;
        if (tree[id].max_preone == tree[id << 1].len)  tree[id].max_preone += tree[id << 1 | 1].max_preone;
        tree[id].max_lastone = tree[id << 1 | 1].max_lastone;
        if (tree[id].max_lastone == tree[id << 1 | 1].len)    tree[id].max_lastone += tree[id << 1].max_lastone;
        tree[id].max_sub = max(tree[id << 1].max_lastone + tree[id << 1 | 1].max_preone, max(tree[id << 1].max_sub, tree[id << 1 | 1].max_sub));
    
        tree[id].max_prezero = tree[id << 1].max_prezero;
        if (tree[id].max_prezero == tree[id << 1].len)    tree[id].max_prezero += tree[id << 1 | 1].max_prezero;
        tree[id].max_lastzero = tree[id << 1 | 1].max_lastzero;
        if (tree[id].max_lastzero == tree[id << 1 | 1].len)    tree[id].max_lastzero += tree[id << 1].max_lastzero;
        tree[id].max_zero = max(tree[id << 1].max_lastzero + tree[id << 1 | 1].max_prezero, max(tree[id << 1].max_zero, tree[id << 1 | 1].max_zero));
    
        return;
    }
    
    void chang1(int id, int val)
    {
        if (val)
        {
            tree[id].sum = tree[id].len;
            tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = tree[id].len;
            tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = 0;
        }
        else
        {
            tree[id].sum = 0;
            tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = 0;
            tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = tree[id].len;
        }
    }
    
    void chang2(int id)
    {
        swap(tree[id].max_sub, tree[id].max_zero);
        swap(tree[id].max_prezero, tree[id].max_preone);
        swap(tree[id].max_lastone, tree[id].max_lastzero);
        tree[id].sum = tree[id].len - tree[id].sum;
    }
    
    void push_down(int id)
    {
        if (tree[id].lazy1)
        {
            chang1(id << 1, tree[id].lazy1 - 1);
            chang1(id << 1 | 1, tree[id].lazy1 - 1);
            tree[id << 1].lazy1 = tree[id << 1 | 1].lazy1 = tree[id].lazy1;
            tree[id << 1].lazy2 =tree[id << 1 | 1].lazy2 = 0;
            tree[id].lazy1 = 0;
        }
        if (tree[id].lazy2)
        {
            chang2(id << 1);
            chang2(id << 1 | 1);
    
            tree[id << 1].lazy2 ^= 1;
            tree[id << 1 | 1].lazy2 ^= 1;
            tree[id].lazy2 = 0;
        }
    }
    
    void build(int id, int l, int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].lazy1 = 0;
        tree[id].lazy2 = 0;
        tree[id].len = r - l + 1;
        if (l == r)
        {
            if (a[l]) chang1(id, 1);
            else chang1(id, 0);
            return;
        }
        int mid = (l + r) >> 1;
        build(id << 1, l, mid);
        build(id << 1 | 1, mid + 1, r);
        push_up(id);
    }
    
    void update_change(int id, int l, int r, int z)
    {
        if (l <= tree[id].l&&r >= tree[id].r)
        {
            chang1(id, z);
            tree[id].lazy1 = z + 1;
            tree[id].lazy2 = 0;
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) >> 1;
        if (l <= mid) update_change(id << 1, l, r, z);
        if (r > mid) update_change(id << 1 | 1, l, r, z);
        push_up(id);
    }
    
    void update_trans(int id, int l, int r)
    {
        if (l <= tree[id].l&&r >= tree[id].r)
        {
            tree[id].lazy2 ^= 1;
            chang2(id);
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) >> 1;
        if (l <= mid) update_trans(id << 1, l, r);
        if (r > mid) update_trans(id << 1 | 1, l, r);
        push_up(id);
    }
    
    int query_sum(int id, int l, int r)
    {
        if (l <= tree[id].l&&r >= tree[id].r)
        {
            return tree[id].sum;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) >> 1, ans = 0;
        if (l <= mid) ans += query_sum(id << 1, l, r);
        if (r > mid) ans += query_sum(id << 1 | 1, l, r);
        return ans;
    }
    
    int query(int id, int l, int r)
    {
        int ans = 0;
        if (l <= tree[id].l&&r >= tree[id].r)
        {
            return tree[id].max_sub;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) >> 1;
        if (l <= mid) ans = max(ans, query(id << 1, l, r));
        if (r > mid) ans = max(ans, query(id << 1 | 1, l, r));
        ans = max(ans, min(mid - l + 1, tree[id << 1].max_lastone) + min(r - mid, tree[id << 1 | 1].max_preone));
        return ans;
    }
    
    int main()
    {
        int t;
        cin >> t;
        while (t--)
        {
            int n, m;
            cin >> n >> m;
            for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
            build(1, 1, n);
            while (m--)
            {
                int c, x, y;
                scanf("%d%d%d", &c, &x, &y);
                if (c == 0) update_change(1, x + 1, y + 1, 0);
                if (c == 1) update_change(1, x + 1, y + 1, 1);
                if (c == 2) update_trans(1, x + 1, y + 1);
                if (c == 3)
                {
                    int ans = query_sum(1, x + 1, y + 1);
                    printf("%d
    ", ans);
                }
                if (c == 4)
                {
                    int ans = query(1, x + 1, y + 1);
                    printf("%d
    ", ans);
                }
            }
        }
        return 0;
    }








     

  • 相关阅读:
    UTF-8 的理解
    P4779 【模板】单源最短路径(标准版)
    Proj THUDBFuzz Paper Reading: FuzzFactory: Domain-Specific Fuzzing with Waypoints
    记一次ctf文件上传
    使用vue创建项目的详细步骤
    Vue进行事件处理的方法(指南
    规则引擎-可视化平台-构思1
    常用正则校验
    tomcat无法启动socket bind failed 的解决方法
    mysql修改root密码
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10809778.html
Copyright © 2020-2023  润新知