• Problem 2 线段树


    $des$

    一个无限长的 01 序列,初始全为 0,每次选择一个区间 [l,r] 进行操作,有三种操作:
    1. l r 将 [l,r] 中所有元素变成 1。
    2. l r 将 [l,r] 中所有元素变成 0。
    3. l r 将 [l,r] 中所有元素异或上 1。
    每次操作后询问最左边的 0 在哪个位置.

    $sol$

    线段树

    将所有可能成为答案的点加入线段树的根节点维护

    $code$

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    
    using namespace std;
    
    #define LL long long
    #define Rep(i, a, b) for(int i = a; i <= b; i ++)
    #define gc getchar()
    
    inline LL read() {
        LL x = 0; char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
    
    const int N = 1e5 + 10, M = N * 6 * 2;
    
    struct Node {
        LL opt, l, r;
    } Ask[N];
    LL A[M], js;
    int n;
    
    struct Node_ {
        int Cnt[2][M << 2], Size[M << 2], F[M << 2];
        
        #define lson jd << 1
        #define rson jd << 1 | 1
        
        void Build_tree(int l, int r, int jd) {
            F[jd] = -1;
            Size[jd] = r - l + 1;
            Cnt[0][jd] = Size[jd];
            if(l == r) return ;
            int mid = (l + r) >> 1;
            Build_tree(l, mid, lson), Build_tree(mid + 1, r, rson);
        }
        
        void Push_down(int jd) {
            int f = F[jd];
            if(f == 1) {
                F[lson] = F[rson] = 1;
                Cnt[1][lson] = Size[lson], Cnt[1][rson] = Size[rson];
                Cnt[0][lson] = 0, Cnt[0][rson] = 0;
                F[jd] = -1;
            } else if(f == 0) {
                F[lson] = F[rson] = 0;
                Cnt[0][lson] = Size[lson], Cnt[0][rson] = Size[rson];
                Cnt[1][lson] = 0, Cnt[1][rson] = 0;
                F[jd] = -1;
            } else {
                if(F[lson] == 2) {
                    swap(Cnt[1][lson], Cnt[0][lson]);
                    F[lson] = -1;
                } else {
                    if(F[lson] == -1) {
                        F[lson] = 2;
                        swap(Cnt[1][lson], Cnt[0][lson]);
                    } else if(F[lson] == 0) {
                        F[lson] = 1;
                        Cnt[1][lson] = Size[lson], Cnt[0][lson] = 0;
                    } else {
                        F[lson] = 0;
                        Cnt[0][lson] = Size[lson], Cnt[1][lson] = 0;
                    }
                }
                if(F[rson] == 2) {
                    swap(Cnt[1][rson], Cnt[0][rson]);
                    F[rson] = -1;
                } else {
                    if(F[rson] == -1) {
                        F[rson] = 2;
                        swap(Cnt[1][rson], Cnt[0][rson]);
                    } else if(F[rson] == 0) {
                        F[rson] = 1;
                        Cnt[1][rson] = Size[rson], Cnt[0][rson] = 0;
                    } else {
                        F[rson] = 0;
                        Cnt[0][rson] = Size[rson], Cnt[1][rson] = 0;
                    }
                }
                F[jd] = -1;
            }
        }
        
        void Sec_G(int l, int r, int jd, int x, int y, int num){
            if(x <= l && r <= y) {
                Cnt[num][jd] = Size[jd];
                Cnt[num ^ 1][jd] = 0;
                F[jd] = num;
    //            cout << Cnt[1][jd] << " " << Cnt[0][jd] << "
    ";
                return ;
            }
            if(F[jd] != -1) Push_down(jd);
            int mid = (l + r) >> 1;
    //        cout << Cnt[0][lson] << "
    ";
            if(x <= mid) Sec_G(l, mid, lson, x, y, num);
            if(y > mid)  Sec_G(mid + 1, r, rson, x, y, num);
            Cnt[1][jd] = Cnt[1][lson] + Cnt[1][rson];
            Cnt[0][jd] = Cnt[0][lson] + Cnt[0][rson];
        }
        
        int Ask(int l, int r, int jd) {
            if(l == r) {
                return l;
            }        
            if(F[jd] != -1) Push_down(jd);
            int mid = (l + r) >> 1;
    //        cout << Cnt[0][lson] << "
    ";
            if(Cnt[0][lson]) return Ask(l, mid, lson);
            else return Ask(mid + 1, r, rson);
        }
        
        void Seg_fz(int l, int r, int jd, int x, int y) {
            if(x <= l && r <= y) {
                if(F[jd] == -1) {
                    swap(Cnt[1][jd], Cnt[0][jd]);
                    F[jd] = 2;
                    return ;                    
                } else if(F[jd] == 0) {
                    F[jd] = 1;
                    Cnt[1][jd] = Size[jd];
                    Cnt[0][jd] = 0;
                } else if(F[jd] == 1) {
                    F[jd] = 0;
                    Cnt[1][jd] = 0;
                    Cnt[0][jd] = Size[jd];
                } else {
                    F[jd] = -1;
                    swap(Cnt[1][jd], Cnt[0][jd]);
                }
                return ;
            }
            if(F[jd] != -1) Push_down(jd);
            int mid = (l + r) >> 1;
    //        cout << Cnt[0][lson] << "
    ";
            if(x <= mid) Seg_fz(l, mid, lson, x, y);
            if(y > mid)  Seg_fz(mid + 1, r, rson, x, y);
            Cnt[1][jd] = Cnt[1][lson] + Cnt[1][rson];
            Cnt[0][jd] = Cnt[0][lson] + Cnt[0][rson];
        }    
    } Segtree;
    
    inline LL Getans() {
        int w = Segtree.Ask(1, js, 1);
    //    if(A[w - 1] + 1 != A[w]) return A[w - 1] + 1;
    //    else return A[w];
        return A[w];
    }
    
    int main() {
        freopen("a.in", "r", stdin);
        freopen("a.out", "w", stdout);
        n = read();
        Rep(i, 1, n) {
            LL opt = read(), l = read(), r = read();
            A[++ js] = l, A[++ js] = r; A[++ js] = max(1ll, l - 1), A[++ js] = r + 1;
            Ask[i] = (Node) {
                opt, l, r
            };
        }
        A[++ js] = 1;
        sort(A + 1, A + js + 1);
        js = unique(A + 1, A + js + 1) - A - 1;
        Segtree.Build_tree(1, js, 1);
    //    Rep(i, 1, 10) cout << Segtree.F[i] << " ";
    //    return 0;
        Rep(i, 1, n) {
            LL opt = Ask[i].opt, l = Ask[i].l, r = Ask[i].r;
            int wl = lower_bound(A + 1, A + js + 1, l) - A;
            int wr = lower_bound(A + 1, A + js + 1, r) - A;
            if(opt == 1) {
                Segtree.Sec_G(1, js, 1, wl, wr, 1);    
                cout << Getans() << "
    ";
            } else if(opt == 2) {
                Segtree.Sec_G(1, js, 1, wl, wr, 0);
                cout << Getans() << "
    ";
            } else {
                Segtree.Seg_fz(1, js, 1, wl, wr);
                cout << Getans() << "
    ";
            }
        }
        
        
        return 0;
    }
  • 相关阅读:
    echarts-五分钟的教程
    vue中的路由
    2x or 3X的图
    background-size cover和contain的用法详解
    吃转基因有害?科普这么多年咋还有人信!
    基于UDP协议的Socket通信
    基于TCP协议Socket通信
    echarts地图
    Ehcache缓存实例
    Tomcat配置绝对路径
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9767459.html
Copyright © 2020-2023  润新知