zoukankan      html  css  js  c++  java
  • Codeforces 803G Periodic RMQ Problem 线段树

    Periodic RMQ Problem

    动态开点线段树直接搞, 我把它分成两部分, 一部分是原来树上的, 一部分是后来染上去的,两个部分取最小值。

    感觉有点难写。。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-6;
    const double PI = acos(-1);
    
    int Log[N];
    int MIN = inf;
    struct ST {
        int dp[N][20], ty;
        void build(int n, int b[], int _ty) {
            ty = _ty;
            for(int i = -(Log[0]=-1); i < N; i++)
            Log[i] = Log[i - 1] + ((i & (i - 1)) == 0);
            for(int i = 1; i <= n; i++) dp[i][0] = ty * b[i];
            for(int j = 1; j <= Log[n]; j++)
                for(int i = 1; i + (1 << j) - 1 <= n; i++)
                    dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
        }
        int query(int x, int y) {
            int k = Log[y - x + 1];
            return ty * max(dp[x][k], dp[y - (1 << k) + 1][k]);
        }
    } rmq;
    
    int n, k, q, a[N];
    
    #define lson l, mid, a[x].ls
    #define rson mid + 1, r, a[x].rs
    namespace SGT1 {
        int tot, Rt;
        struct Node {
            Node() {
                mn = inf;
                ls = rs = 0;
                lazy = inf;
            }
            int mn, ls, rs, lazy;
        } a[N * 25];
        inline void pull(int x) {
            a[x].mn = min(a[a[x].ls].mn, a[a[x].rs].mn);
        }
        inline void push(int x) {
            if(a[x].lazy < inf) {
                if(!a[x].ls) a[x].ls = ++tot;
                if(!a[x].rs) a[x].rs = ++tot;
                int lazy = a[x].lazy, l = a[x].ls, r = a[x].rs;
                a[l].mn = lazy;
                a[r].mn = lazy;
                a[l].lazy = lazy;
                a[r].lazy = lazy;
                a[x].lazy = inf;
            }
        }
        void update(int L, int R, int val, int l, int r, int& x) {
            if(!x) x = ++tot;
            if(l >= L && r <= R) {
                a[x].mn = val;
                a[x].lazy = val;
                return;
            }
            push(x);
            int mid = l + r >> 1;
            if(L <= mid) update(L, R, val, lson);
            if(R > mid)  update(L, R, val, rson);
            pull(x);
        }
        int query(int L, int R, int l, int r, int x) {
            if(l >= L && r <= R) return a[x].mn;
            push(x);
            int mid = l + r >> 1;
            if(R <= mid) return query(L, R, lson);
            else if(L > mid) return query(L, R, rson);
            else return min(query(L, R, lson), query(L, R, rson));
        }
    }
    
    namespace SGT2 {
        int tot, Rt;
        struct Node {
            Node() {
                ls = rs = 0;
                mn = inf;
                vis = false;
            }
            int mn, ls, rs;
            bool vis;
        } a[N * 25];
        void update(int L, int R, int l, int r, int& x) {
            if(!x) {
                x = ++tot;
                if(r - l + 1 >= n) a[x].mn = MIN;
                else {
                    int be = (l - 1) % n + 1;
                    int ed = be + (r - l);
                    a[x].mn = rmq.query(be, ed);
                }
            }
            if(a[x].vis) return;
            if(l >= L && r <= R) {
                a[x].mn = inf;
                a[x].vis = true;
                return;
            }
            int mid = l + r >> 1;
            if(R <= mid) {
                update(L, R, lson);
                if(!a[x].rs) {
                    a[x].rs = ++tot;
                    if(r - mid >= n) {
                        a[a[x].rs].mn = MIN;
                    } else {
                        int be = (mid) % n + 1;
                        int ed = be + (r - mid) - 1;
                        a[a[x].rs].mn = rmq.query(be, ed);
                    }
                }
            } else if(L > mid) {
                update(L, R, rson);
                if(!a[x].ls) {
                    a[x].ls = ++tot;
                    if(mid - l + 1 >= n) {
                        a[a[x].ls].mn = MIN;
                    } else {
                        int be = (l - 1) % n + 1;
                        int ed = be + (mid - l);
                        a[a[x].ls].mn = rmq.query(be, ed);
                    }
                }
            } else {
                update(L, R, lson);
                update(L, R, rson);
            }
            a[x].mn = min(a[a[x].ls].mn, a[a[x].rs].mn);
        }
        int query(int L, int R, int l, int r, int& x) {
            if(!x) {
                x = ++tot;
                if(r - l + 1 >= n) a[x].mn = MIN;
                else {
                    int be = (l - 1) % n + 1;
                    int ed = be + (r - l);
                    a[x].mn = rmq.query(be, ed);
                }
            }
            if(a[x].vis) return inf;
            if(l >= L && r <= R) return a[x].mn;
            int mid = l + r >> 1;
            if(R <= mid) return query(L, R, lson);
            else if(L > mid) return query(L, R, rson);
            else return min(query(L, R, lson), query(L, R, rson));
        }
    }
    
    
    int main() {
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            a[i + n] = a[i];
            MIN = min(MIN, a[i]);
        }
        rmq.build(2 * n, a, -1);
        scanf("%d", &q);
        while(q--) {
            int op; scanf("%d", &op);
            if(op == 1) {
                int L, R, x;
                scanf("%d%d%d", &L, &R, &x);
                SGT1::update(L, R, x, 1, n * k, SGT1::Rt);
                SGT2::update(L, R, 1, n * k, SGT2::Rt);
            } else {
                int L, R;
                scanf("%d%d", &L, &R);
                printf("%d
    ", min(SGT1::query(L, R, 1, n * k, SGT1::Rt), SGT2::query(L, R, 1, n * k, SGT2::Rt)));
            }
        }
        return 0;
    }
    
    /*
    */

    简化

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-6;
    const double PI = acos(-1);
    
    int Log[N];
    int MIN = inf;
    struct ST {
        int dp[N][20], ty;
        void build(int n, int b[], int _ty) {
            ty = _ty;
            for(int i = -(Log[0]=-1); i < N; i++)
            Log[i] = Log[i - 1] + ((i & (i - 1)) == 0);
            for(int i = 1; i <= n; i++) dp[i][0] = ty * b[i];
            for(int j = 1; j <= Log[n]; j++)
                for(int i = 1; i + (1 << j) - 1 <= n; i++)
                    dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
        }
        int query(int x, int y) {
            int k = Log[y - x + 1];
            return ty * max(dp[x][k], dp[y - (1 << k) + 1][k]);
        }
    } rmq;
    
    int n, k, q, a[N];
    
    inline int getVal(int l, int r) {
        if(r - l + 1 >= n) return MIN;
        int be = (l - 1) % n + 1;
        int ed = be + (r - l);
        return rmq.query(be, ed);
    }
    
    #define lson l, mid, a[x].ls
    #define rson mid + 1, r, a[x].rs
    namespace SGT {
        int tot, Rt;
        struct Node {
            Node() {
                mn = inf;
                ls = rs = 0;
                lazy = inf;
            }
            int mn, ls, rs, lazy;
        } a[N * 25];
        inline void pull(int x) {
            a[x].mn = min(a[a[x].ls].mn, a[a[x].rs].mn);
        }
        inline void push(int x, int l, int r) {
            int mid = l + r >> 1;
            if(!a[x].ls) {
                a[x].ls = ++tot;
                a[a[x].ls].mn = getVal(l, mid);
            }
            if(!a[x].rs) {
                a[x].rs = ++tot;
                a[a[x].rs].mn = getVal(mid + 1, r);
            }
            if(a[x].lazy < inf) {
                int lazy = a[x].lazy, l = a[x].ls, r = a[x].rs;
                a[l].mn = lazy;
                a[r].mn = lazy;
                a[l].lazy = lazy;
                a[r].lazy = lazy;
                a[x].lazy = inf;
            }
        }
        void update(int L, int R, int val, int l, int r, int& x) {
            if(!x) x = ++tot;
            if(l >= L && r <= R) {
                a[x].mn = val;
                a[x].lazy = val;
                return;
            }
            push(x, l, r);
            int mid = l + r >> 1;
            if(L <= mid) update(L, R, val, lson);
            if(R > mid)  update(L, R, val, rson);
            pull(x);
        }
        int query(int L, int R, int l, int r, int x) {
            if(l >= L && r <= R) {
                if(!x) return getVal(l, r);
                return a[x].mn;
            }
            push(x, l, r);
            int mid = l + r >> 1;
            if(R <= mid) return query(L, R, lson);
            else if(L > mid) return query(L, R, rson);
            else return min(query(L, R, lson), query(L, R, rson));
        }
    }
    
    int main() {
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            a[i + n] = a[i];
            MIN = min(MIN, a[i]);
        }
        rmq.build(2 * n, a, -1);
        scanf("%d", &q);
        while(q--) {
            int op; scanf("%d", &op);
            if(op == 1) {
                int L, R, x;
                scanf("%d%d%d", &L, &R, &x);
                SGT::update(L, R, x, 1, n * k, SGT::Rt);
            } else {
                int L, R;
                scanf("%d%d", &L, &R);
                printf("%d
    ", SGT::query(L, R, 1, n * k, SGT::Rt));
            }
        }
        return 0;
    }
    
    /*
    */

    指针

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-6;
    const double PI = acos(-1);
    
    int Log[N];
    int MIN = inf;
    struct ST {
        int dp[N][20], ty;
        void build(int n, int b[], int _ty) {
            ty = _ty;
            for(int i = -(Log[0]=-1); i < N; i++)
            Log[i] = Log[i - 1] + ((i & (i - 1)) == 0);
            for(int i = 1; i <= n; i++) dp[i][0] = ty * b[i];
            for(int j = 1; j <= Log[n]; j++)
                for(int i = 1; i + (1 << j) - 1 <= n; i++)
                    dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
        }
        int query(int x, int y) {
            int k = Log[y - x + 1];
            return ty * max(dp[x][k], dp[y - (1 << k) + 1][k]);
        }
    } rmq;
    
    int n, k, q, a[N];
    
    inline int getVal(int l, int r) {
        if(r - l + 1 >= n) return MIN;
        int be = (l - 1) % n + 1;
        int ed = be + (r - l);
        return rmq.query(be, ed);
    }
    
    struct Node {
        Node* ls, *rs;
        int mn, lazy;
        Node(int l, int r) {
            ls = rs = NULL;
            mn = getVal(l, r);
            lazy = -1;
        }
    };
    
    #define lson l, mid, rt->ls
    #define rson mid + 1, r, rt->rs
    
    inline void pull(Node* rt) {
        rt->mn = min(rt->ls->mn, rt->rs->mn);
    }
    inline void push(Node* rt, int l, int r) {
        int mid = l + r >> 1;
        if(!rt->ls) rt->ls = new Node(l, mid);
        if(!rt->rs) rt->rs = new Node(mid + 1, r);
        if(rt->lazy != -1) {
            rt->ls->mn = rt->ls->lazy = rt->lazy;
            rt->rs->mn = rt->rs->lazy = rt->lazy;
            rt->lazy = -1;
        }
    }
    
    void update(int L, int R, int val, int l, int r, Node* rt) {
        if(R < l || L > r) return;
        if(l >= L && r <= R) {
            rt->mn = rt->lazy = val;
            return;
        }
        push(rt, l, r);
        int mid = l + r >> 1;
        update(L, R, val, lson);
        update(L, R, val, rson);
        pull(rt);
    }
    
    int query(int L, int R, int l, int r, Node* rt) {
        if(R < l || L > r) return inf;
        if(l >= L && r <= R) {
            if(rt) return rt->mn;
            else return getVal(l, r);
        }
        push(rt, l, r);
        int mid = l + r >> 1;
        return min(query(L, R, lson), query(L, R, rson));
    }
    
    int main() {
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            a[i + n] = a[i];
            MIN = min(MIN, a[i]);
        }
        rmq.build(2 * n, a, -1);
        Node* Rt = new Node(1, n * k);
        scanf("%d", &q);
        while(q--) {
            int op; scanf("%d", &op);
            if(op == 1) {
                int L, R, x;
                scanf("%d%d%d", &L, &R, &x);
                update(L, R, x, 1, n * k, Rt);
            } else {
                int L, R;
                scanf("%d%d", &L, &R);
                printf("%d
    ", query(L, R, 1, n * k, Rt));
            }
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    远程连接桌面报:这可能是由于credssp加密oracle修正
    MVC断点续传
    [COCI2011-2012#5] POPLOCAVANJE 后缀自动机
    [SDOI2016]生成魔咒 后缀自动机
    [JSOI2009]密码 AC自动机
    CF17E Palisection manacher
    [JSOI2007]字符加密 后缀数组
    [POI2012]OKR-A Horrible Poem hash
    [APIO2014]回文串 manacher 后缀数组
    [SHOI2011]双倍回文 manacher
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10657808.html
Copyright © 2011-2022 走看看