• hdu 3397 Sequence operation 线段树 区间更新 区间合并


    题意:

    5种操作,所有数字都为0或1

    0 a b:将[a,b]置0

    1 a b:将[a,b]置1

    2 a b:[a,b]中的0和1互换

    3 a b:查询[a,b]中的1的数量

    4 a b:查询[a,b]中的最长连续1串的长度

    这题看题目就很裸,综合了区间更新,区间合并

    我一开始把更新操作全放一个变量,但是在push_down的时候很麻烦,情况很多,容易漏,后来改成下面的

    更新的操作可以分为两类,一个是置值(stv),一个是互换(swp)。如果stv!=-1,则更新儿子节点的stv,并将儿子的swp=0。如果swp=1,这里要注意一点,不是把儿子的swp赋值为1,而是与1异或!!!因为如果儿子的swp本为1,再互换一次,两个互换就相当于值没有变了。

    注意下细节就行了

    #include <bits/stdc++.h>
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    
    const int MAXN = 111111;
    
    struct Node
    {
        int num1, stv, swp;
        int mx0, lmx0, rmx0;
        int mx1, lmx1, rmx1;
    } tr[MAXN<<2];
    
    void changeto(int rt, int to,int len)
    {
        tr[rt].mx0 = tr[rt].lmx0 = tr[rt].rmx0 = to? 0 : len;
        tr[rt].mx1 = tr[rt].lmx1 = tr[rt].rmx1 = tr[rt].num1 = to? len : 0;
    }
    
    void exchange(int rt, int len)
    {
        tr[rt].num1 = len - tr[rt].num1;
        swap(tr[rt].mx0, tr[rt].mx1);
        swap(tr[rt].lmx0, tr[rt].lmx1);
        swap(tr[rt].rmx0, tr[rt].rmx1);
    }
    
    void push_down(int rt, int len)
    {
        if(tr[rt].stv != -1)
        {
            tr[rt<<1].stv = tr[rt<<1|1].stv = tr[rt].stv;
            tr[rt<<1].swp = tr[rt<<1|1].swp = 0;
            changeto(rt<<1, tr[rt].stv, len-(len>>1));
            changeto(rt<<1|1, tr[rt].stv, len>>1);
            tr[rt].stv = -1;
        }
        if(tr[rt].swp == 1)
        {
            tr[rt<<1].swp ^= 1;
            tr[rt<<1|1].swp ^= 1;
            exchange(rt<<1, len-(len>>1));
            exchange(rt<<1|1, len>>1);
            tr[rt].swp = 0;
        }
    }
    
    void push_up(int rt, int len)
    {
        tr[rt].num1 = tr[rt<<1].num1 + tr[rt<<1|1].num1;
    
        tr[rt].lmx0 = tr[rt<<1].lmx0;
        tr[rt].rmx0 = tr[rt<<1|1].rmx0;
        if(tr[rt].lmx0 == len - (len >> 1)) tr[rt].lmx0 += tr[rt<<1|1].lmx0;
        if(tr[rt].rmx0 == len >> 1) tr[rt].rmx0 += tr[rt<<1].rmx0;
        tr[rt].mx0 = max(tr[rt<<1].rmx0 + tr[rt<<1|1].lmx0, max(tr[rt<<1].mx0, tr[rt<<1|1].mx0));
    
        tr[rt].lmx1 = tr[rt<<1].lmx1;
        tr[rt].rmx1 = tr[rt<<1|1].rmx1;
        if(tr[rt].lmx1 == len - (len >> 1)) tr[rt].lmx1 += tr[rt<<1|1].lmx1;
        if(tr[rt].rmx1 == len >> 1) tr[rt].rmx1 += tr[rt<<1].rmx1;
        tr[rt].mx1 = max(tr[rt<<1].rmx1 + tr[rt<<1|1].lmx1, max(tr[rt<<1].mx1, tr[rt<<1|1].mx1));
    }
    
    void build(int l, int r, int rt)
    {
        tr[rt].stv = -1;
        tr[rt].swp = 0;
        if(l == r)
        {
            scanf("%d", &tr[rt].num1);
            tr[rt].mx0 = tr[rt].lmx0 = tr[rt].rmx0 = tr[rt].num1 ^ 1;
            tr[rt].mx1 = tr[rt].lmx1 = tr[rt].rmx1 = tr[rt].num1;
            return;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        push_up(rt, r-l+1);
    }
    
    void update(int L, int R, int op, int l, int r, int rt)
    {
        if(L <= l && r <= R)
        {
            if(op == 0 || op == 1)
            {
                changeto(rt, op, r-l+1);
                tr[rt].stv = op;
                tr[rt].swp = 0;
            }
            else
            {
                exchange(rt, r-l+1);
                tr[rt].swp ^= 1;
            }
            return;
        }
        push_down(rt, r-l+1);
        int m = (l + r) >> 1;
        if(m >= L) update(L, R, op, lson);
        if(m < R) update(L, R, op, rson);
        push_up(rt, r-l+1);
    }
    
    int query1(int L, int R, int l, int r, int rt)
    {
        if(L <= l && r <= R) return tr[rt].num1;
        push_down(rt, r-l+1);
        int m = (l + r) >> 1;
        int ret = 0;
        if(m >= L) ret += query1(L, R, lson);
        if(m < R) ret += query1(L, R, rson);
        return ret;
    }
    
    int query2(int L, int R, int l, int r, int rt)
    {
        if(L <= l && r <= R) return tr[rt].mx1;
        push_down(rt, r-l+1);
        int m = (l + r) >> 1;
        int ret = 0;
        if(m >= L) ret = max(ret, query2(L, R, lson));
        if(m < R) ret = max(ret, query2(L, R, rson));
        ret = max(ret, min(tr[rt<<1].rmx1, m-L+1) + min(tr[rt<<1|1].lmx1, R-m));
        return ret;
    }
    
    int main()
    {
    //    freopen("in.txt", "r", stdin);
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int n, m;
            scanf("%d%d", &n, &m);
            build(0, n-1, 1);
            while(m--)
            {
                int op, x, y;
                scanf("%d%d%d", &op, &x, &y);
                if(op <= 2) update(x, y, op, 0, n-1, 1);
                else if(op == 3) printf("%d
    ", query1(x, y, 0, n-1, 1));
                else printf("%d
    ", query2(x, y, 0, n-1, 1));
            }
        }
        return 0;
    }
  • 相关阅读:
    Java 零基础跑起第一个程序
    Xcode6 引入第三方静态库project的方法
    Cocos2d-x3.0 RenderTexture(三)
    POJ 题目3461 Oulipo(KMP)
    unity3D游戏开发实战原创视频讲座系列9之塔防类游戏开发第一季
    android 虚拟按键是通过哪种机制上报的?
    深入理解 C 指针阅读笔记 -- 第五章
    【1】按照Django官网,编写一个web app 创建project/配置数据库
    [Swift]LeetCode442. 数组中重复的数据 | Find All Duplicates in an Array
    [Swift]LeetCode441. 排列硬币 | Arranging Coins
  • 原文地址:https://www.cnblogs.com/pach/p/7452298.html
Copyright © 2020-2023  润新知