zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Oracle SQL语句收集
    SqlParameter In 查询
    SQL 性能优化
    Entity Framework
    【XLL API 函数】 xlfSetName
    【XLL API 函数】xlfUnregister (Form 2)
    【XLL API 函数】xlfUnregister (Form 1)
    【Excel 4.0 函数】REGISTER 的两种形式以及VBA等效语句
    【Excel 4.0 函数】REGISTER
    【Bochs 官方手册翻译】 第一章 Bochs介绍
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9767459.html
Copyright © 2011-2022 走看看