[Zhx] 无题

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\n");
            else cout << zz.nm[k - 1] <<"\n";
        }
        if(op == 1) {int l = read(), r = read(), v = read(); add(1, n, 1, l, r, v);}
    }
    return 0;
}

 

posted @ 2018-01-09 21:23  xayata  阅读(139)  评论(0编辑  收藏  举报