CF803G - Periodic RMQ Problem dynamic prescription segment tree or offline

CF

The meaning of problems

It has a length of n × k (<= 1E9) of the array, and modifying section has minimum interval query operations.

Thinking

Since the array is too large, direct obviously do not.

There are two approaches you can use the dynamic version of the prescription segment tree, or engage in off-line (not out).

Note that only the 1E5 operations, it really is not much to update the interval, the worst single newly opened 2 × log (1E9).

For the minimum value of the newly opened interval, can be calculated, if the value is greater than the interval represented by n, that is the original length of the minimum of the interval n, less than n, then the query can be in a table ST.

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;


template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); }


template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}

const int inf = 0x3f3f3f3f;

const int mod = 1e9+7;

/**********showtime************/

            const int maxn = 1e5+9;
            int b[maxn];

            int st[maxn][22], Log[maxn];
            void init_st(int n) {
                Log[0] = -1;
                for(int i=1; i<=n; i++) {
                    Log[i] = Log[i>>1] + 1;
                    st[i][0] = b[i];
                }
                for(int j=1; (1<<j) <= n; j++) {
                    for(int i=1; i + (1<<j) -1 <= n; i++) {
                        st[i][j] = min(st[i][j-1], st[i+ (1<<(j-1))][j-1]);
                    }
                }
            }
            int rmq_st(int L, int R) {
                int k = Log[R - L + 1];
                return min(st[L][k], st[R-(1<<k)+1][k]);
            }
            int n,k;
            int getmin(int le, int ri) {
                if(ri - le + 1 >= n) return rmq_st(1, n);
                int L = le % n; if(L == 0) L = n;
                int R = ri % n; if(R == 0) R = n;
                if(L <= R) return rmq_st(L, R);
                return min(rmq_st(L, n), rmq_st(1, R));
            }
            struct Node{
                int le, ri;
                int lc,rc;
                int val, tag;
            } tree[maxn * 60];
            int tot = 0 ;
            int newNode ( int a, int n) { 
                tot ++ ; 
                tree [tot] .the = the; 
                tree [tot] .ri = ri; 
                tree [tot] .lc = tree [tot] .rc = 0 ; 
                tree [tot] .val = getMin (le, ri); 
                tree [tot] .tag = 0 ;
                return tot; 
            } 
            Void pushdown ( int rt) { 
                tree [tree [rt] .lc] .val= tree[tree[rt].lc].tag = tree[rt].tag;
                tree[tree[rt].rc].val = tree[tree[rt].rc].tag = tree[rt].tag;
                tree[rt].tag = 0;
            }
            void update(int L, int R, int b, int rt) {
                if(L<=tree[rt].le && tree[rt].ri <= R) {
                    tree[rt].val = tree[rt].tag = b;
                    return;
                }
                int mid = (tree[rt].le + tree[rt].ri) >> 1;
                if(tree[rt].lc == 0) tree[rt].lc = newNode(tree[rt].le, mid);
                if(tree[rt].rc == 0) tree[rt].rc = newNode(mid+1, tree[rt].ri);
                if(tree[rt].tag) pushdown(rt);
                if(mid >= L) update(L, R, b, tree[rt].lc);
                if(mid < R) update(L, R, b, tree[rt].rc);
                tree[rt].val = min(tree[tree[rt].lc].val, tree[tree[rt].rc].val);
            }
            int query(int L, int R, int rt) {
                if(L <= tree[rt].le && tree[rt].ri <= R) {
                    return tree[rt].val;
                }

                int mid = (tree[rt].le + tree[rt].ri) >> 1;
                if(tree[rt].lc == 0) tree[rt].lc = newNode(tree[rt].le, mid);
                if(tree[rt].rc == 0) tree[rt].rc = newNode(mid+1, tree[rt].ri);
                if(tree[rt].tag) pushdown(rt);
                int res = inf;
                if(mid >= L) res = min(res, query(L, R, tree[rt].lc));
                if(mid < R) res = min(res, query(L, R, tree[rt].rc));
                tree[rt].val = min(tree[tree[rt].lc].val, tree[tree[rt].rc].val);
                return res;
            }
int main(){
            scanf("%d%d", &n, &k);
            for(int i=1; i<=n; i++) scanf("%d", &b[i]);
            init_st(n);
            int q;  scanf("%d", &q);
            newNode(1, n * k);
            while(q--) {
                int op;
                scanf("%d", &op);
                if(op == 1) {
                    int le,ri,x;
                    scanf("%d%d%d", &le, &ri, &x);
                    update(le, ri, x, 1);
                }
                else {
                    int le, ri;
                    scanf("%d%d", &le, &ri);
                    printf("%d\n", query(le, ri, 1));
                }
            }
            return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/ckxkexing/p/11203490.html