https://www.luogu.org/problemnew/show/T15368
区间修改,区间查询k(<= 10)大值
应该也可以用分块写
#include <cstdio> #include<algorithm> #include<iostream> #include<cstring> #define N 100010 #define tq getchar() using namespace std; struct Note { long long nm[10]; int top; Note() {memset(nm,0,sizeof(nm));top = 0;} } note[N << 2],zero_; long long lazy[N << 2]; int n, m; inline int read(){ int x = 0; char c = tq; while(c < '0' || c > '9') c = tq; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = tq; return x; } inline Note mer(Note a, Note b) { if(a.top == 0) return b; if(b.top == 0) return a; Note ans; int ln = 0,rn = 0; while(ln < a.top && rn < b.top) { if(a.nm[ln] > b.nm[rn]) {ans.nm[ans.top] = a.nm[ln]; ln ++;} else {ans.nm[ans.top] = b.nm[rn]; rn ++;} ans.top ++; if(ans.top == 10)break; } while(ln < a.top) { if(ans.top == 10) break; ans.nm[ans.top] = a.nm[ln]; ans.top ++; ln ++; } while(rn < b.top) { if(ans.top == 10) break; ans.nm[ans.top] = b.nm[rn]; ans.top ++; rn ++; } return ans; } inline void Update(int now) {note[now] = mer(note[now << 1],note[now << 1 | 1]);} inline void pushdown(int now) { if(lazy[now]) { lazy[now << 1] += lazy[now]; lazy[now << 1 | 1] += lazy[now]; int lson = now << 1; int rson = now << 1 | 1; for(int i = 0; i < note[lson].top; i++) note[lson].nm[i] += lazy[now]; for(int i = 0; i < note[rson].top; i++) note[rson].nm[i] += lazy[now]; lazy[now] = 0; } } void build(int l, int r, int now) { if(l == r) { note[now].top = 1; note[now].nm[0] = read(); return; } int mid = (l + r) >> 1; build(l, mid, now << 1); build(mid + 1, r, now << 1 | 1); Update(now); } Note query(int l, int r, int now, int ln, int rn) { if(l > rn || r < ln) return zero_; if(l >= ln && r <= rn) return note[now]; pushdown(now); int mid = (l + r) >> 1; Note lx = query(l, mid, now << 1, ln, rn); Note rx = query(mid + 1, r, now << 1 | 1, ln, rn); return mer(lx,rx); } void add(int l, int r, int now, int ln, int rn, int v) { if(l > rn || r < ln) return; if(l >= ln && r <= rn) { lazy[now] += v; for(int i = 0; i < note[now].top; i++) note[now].nm[i] += v; return; } pushdown(now); int mid = (l + r) >> 1; add(l, mid, now << 1, ln, rn, v); add(mid + 1, r, now << 1 | 1, ln, rn, v); Update(now); } int main() { n = read(); m = read(); build(1,n,1); while(m--){ int op = read(); if(op == 0) { int l = read(),r = read(),k = read(); Note zz = query(1, n, 1, l, r); if(zz.top < k) printf("-1 "); else cout << zz.nm[k - 1] <<" "; } if(op == 1) {int l = read(), r = read(), v = read(); add(1, n, 1, l, r, v);} } return 0; }