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\n", min(SGT1::query(L, R, 1, n * k, SGT1::Rt), SGT2::query(L, R, 1, n * k, SGT2::Rt)));
        }
    }
    return 0;
}

/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/10657808.html