动态开点线段树直接搞, 我把它分成两部分, 一部分是原来树上的, 一部分是后来染上去的,两个部分取最小值。
感觉有点难写。。
#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; } /* */