cf545(线段树 + 离散化)

简介: cf545(线段树 + 离散化)

维护一个01串,一开始全部都是0


3种操作


1.把一个区间都变为1


2.把一个区间都变为0


3.把一个区间的所有数字翻转过来


每次操作完成之后询问区间最小的0的位置


l,r<=10^18


思路:先离散化(注意一定要把1也离散进去) 然后对每个区间[l,r] 把l-1,r+1也离散进去,最后维护一颗线段树(维护最大值和最小值)

#include <bits/stdc++.h>
#define lson i<<1
#define rson i<<1|1
using namespace std;
const int maxn = 5e6 + 5;
typedef long long ll;
struct Tree {
    int l, r;
    int mm, mx, lazy;
}tree[maxn];
ll Hash[maxn], len;
void pushup(int i) {
    tree[i].mx = max(tree[lson].mx, tree[rson].mx);
    tree[i].mm = min(tree[lson].mm, tree[rson].mm);
}
void check(int i) {
    if (tree[i].mx == 0) {
        tree[i].mm = tree[i].mx = 1;
    } else if (tree[i].mm == 1) {
        tree[i].mm = tree[i].mx = 0;
    }
}
void pushdown(int i) {
    if (tree[i].lazy == 0) return ;
    if (tree[i].lazy == 1) {
        tree[lson].mm = tree[lson].mx = 1;
        tree[rson].mm = tree[rson].mx = 1;
        tree[lson].lazy = 1; tree[rson].lazy = 1;
    } else if (tree[i].lazy == 2) {
        tree[lson].mm = tree[lson].mx = 0;
        tree[rson].mm = tree[rson].mx = 0;
        tree[lson].lazy = 2; tree[rson].lazy = 2;
    } else if (tree[i].lazy == 3) {
        if (tree[lson].lazy == 3) {
            check(lson); tree[lson].lazy = 0;
        } else if (tree[lson].lazy == 1) {
            check(lson); tree[lson].lazy = 2;
        } else if (tree[lson].lazy == 2) {
            check(lson); tree[lson].lazy = 1;
        } else if (tree[lson].lazy == 0) {
            check(lson); tree[lson].lazy = 3;
        }
        if (tree[rson].lazy == 3) {
            check(rson); tree[rson].lazy = 0;
        } else if (tree[rson].lazy == 1) {
            check(rson); tree[rson].lazy = 2;
        } else if (tree[rson].lazy == 2) {
            check(rson); tree[rson].lazy = 1;
        } else if (tree[rson].lazy == 0) {
            check(rson); tree[rson].lazy = 3;
        }
    }
    tree[i].lazy = 0;
}
void build(int i, int l, int r) {
    tree[i].l = l;
    tree[i].r = r;
    if (l >= r) return ;
    int mid = (l + r) / 2;
    build(lson, l, mid);
    build(rson, mid + 1, r);
    pushup(i);
}
struct node {
    ll opt, l, r;
}q[maxn];
void updata(int i, int l, int r, int opt) {
    pushdown(i);
    int x = tree[i].l, y = tree[i].r;
    if (tree[i].l == l && tree[i].r == r) {
        if (opt == 1) {
            tree[i].mm = tree[i].mx = tree[i].lazy = 1;
        } else if (opt == 2) {
            tree[i].mm = tree[i].mx = 0; tree[i].lazy = 2;
        } else if (opt == 3) {
            if (tree[i].mx == 0) {
                tree[i].mm = tree[i].mx = 1;
            } else if (tree[i].mm == 1) {
                tree[i].mm = tree[i].mx = 0;
            }
            tree[i].lazy = 3;
        }
        return ;
    }
    int mid = (tree[i].l + tree[i].r) / 2;
    if (mid >= r) {
        updata(lson, l, r, opt);
    } else if (l > mid) {
        updata(rson, l, r, opt);
    } else {
        updata(lson, l, mid, opt);
        updata(rson, mid + 1, r, opt);
    }
    pushup(i);
}
ll query(int i) {
    pushdown(i);
    if (tree[i].l == tree[i].r) {
        return tree[i].l;
    }
    int mid = (tree[i].l + tree[i].r) / 2;
    if (tree[i * 2].mm == 0) {
        return query(lson);
    } else {
        return query(rson);
    }
}
/**/
int main() {
    int n;
    scanf("%d", &n);
    Hash[++len] = 1;
    for (int i = 1; i <= n; i++) {
        scanf("%lld%lld%lld", &q[i].opt, &q[i].l, &q[i].r);
        Hash[++len] = q[i].l; Hash[++len] = max(q[i].l - 1, 1LL);
        Hash[++len] = q[i].r; Hash[++len] = q[i].r + 1;
    }
    sort (Hash + 1, Hash + len + 1);
    len = unique(Hash + 1, Hash + len + 1) - Hash - 1;
    build(1, 1, len);
    for (int i = 1; i <= n; i++) {
        q[i].l = lower_bound(Hash + 1, Hash + len + 1, q[i].l) - Hash;
        q[i].r = lower_bound(Hash + 1, Hash + len + 1, q[i].r) - Hash;
        updata(1, q[i].l, q[i].r, q[i].opt);
        printf("%lld\n", Hash[query(1)]);
    }
    return 0;
}
相关文章
|
3月前
|
算法 C语言
分治法——找众数
分治法——找众数
|
3月前
|
算法 测试技术 C#
【二分查找】LeetCode1970:你能穿过矩阵的最后一天
【二分查找】LeetCode1970:你能穿过矩阵的最后一天
|
9月前
|
存储 算法 C++
C++基础算法离散化及区间合并篇
C++基础算法离散化及区间合并篇
102 0
|
3月前
|
算法 测试技术 C#
【动态规划】【前缀和】【和式变换】100216. K 个不相交子数组的最大能量值
【动态规划】【前缀和】【和式变换】100216. K 个不相交子数组的最大能量值
|
9月前
分治法求解中位数
分治法求解中位数
53 0
|
人工智能 算法
动态规划之区间一维
噩梦中的仙境:动态规划之区间一维
49 0
动态规划之区间一维
|
算法
一道线段树相关算法题
每个方块都从一个比目前所有的落地方块更高的高度掉落而下。方块沿 y 轴负方向下落,直到着陆到 另一个正方形的顶边 或者是 x 轴上 。一个方块仅仅是擦过另一个方块的左侧边或右侧边不算着陆。一旦着陆,它就会固定在原地,无法移动。
78 0
一道线段树相关算法题
|
移动开发 算法
一、基础算法(快排,归并,二分,高精度,前缀和,差分)
基础算法(快排,归并,二分,高精度,前缀和,差分)
66 0
|
算法 关系型数据库 MySQL
前缀和和差分和dijkstra算法和二分算法和floyd算法
前缀和和差分和dijkstra算法和二分算法和floyd算法
|
机器学习/深度学习 存储 算法
区间合并算法
区间合并算法