萌新刚学数据结构,求助卡常
查看原帖
萌新刚学数据结构,求助卡常
486187
vvautedSN第一魔怔人楼主2021/10/2 21:41
#include <stdio.h>
#include <math.h>
#include <algorithm>
#define Maxn 100005
#define Maxlen 320
#define inf 1000000000

int n, m, a[Maxn], b[Maxn], belong[Maxn], L[Maxlen], R[Maxlen], tag[Maxlen], len, tot, ans, l, r, mid;
int *tmp;

#define min(a, b) ( a < b ? a : b );  

inline void rebuild(int x) {
    for(register int i = L[x]; i <= R[x]; ++ i)  a[i] = b[i];
    std :: sort(a + L[x], a + R[x] + 1);
}

inline void upd(int l, int r, int k) {
    if(belong[l] == belong[r]) {
        for(register int i = l; i <= r; ++ i) b[i] += k;
        rebuild(belong[l]);
        return;
    }
    register int i;
    for(i = l; i < L[belong[l] + 1]; ++ i) b[i] += k ;
    for(i = belong[l] + 1; i < belong[r]; ++ i) tag[i] += k;
    for(i = L[belong[r]]; i <= r; ++ i) b[i] += k;
    rebuild(belong[l]), rebuild(belong[r]);
}

inline int ranking(int l, int r, int val) {
    int ans = 0;
    if(belong[l] == belong[r]) {
        for(register int i = l; i <= r; ++ i) if(b[i] + tag[belong[i]] <= val) ++ ans;
        return ans;
    }
    register int i;
    for(i = l; i < L[belong[l] + 1]; ++ i) if(b[i] + tag[belong[l]] <= val) ++ ans;
    for(i = belong[l] + 1; i < belong[r]; ++ i) ans += (tmp = (std :: upper_bound(a + L[i], a + R[i] + 1, val - tag[i]))) == (a + R[i] + 1) ? R[i] - L[i] + 1 : tmp - (a + L[i]); 
    for(i = L[belong[r]]; i <= r; ++ i) if(b[i] + tag[belong[r]] <= val) ++ ans;
    return ans;    
}

inline int findkth(int bg, int ed, int k) {
    if(k < 1) return -1;
    if(k > ed - bg + 1)  return -1;
    register int ans = -1, l = - inf, r = inf;
    while(l <= r) {
        mid = l + r >> 1;
    //printf("rank = %d l = %d r = %d mid = %d ans = %d k = %d\n", ranking(bg, ed, mid), l , r, mid, ans, k);
        if(ranking(bg, ed, mid) >= k) ans = mid, r = mid - 1;
        else l = mid + 1;
    //  printf("rank = %d l = %d r = %d mid = %d ans = %d\n", ranking(bg, ed, mid), l , r, mid, ans);
    }
    return ans;
}

int read() {
    register int ch = getchar(), res = 0, tag = 1;
    while(ch < '0' || ch > '9') {
        if(ch == '-') tag = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') res = (res << 3) + (res << 1) + (ch ^ 48), ch = getchar();
    return tag * res; 
}
int main() {
    n = read(), m = read();
    len = (int)sqrt(n);
    tot = (n - 1) / len + 1;
    for(int i = 1; i <= tot; ++ i) {
        L[i] = R[i - 1] + 1, R[i] = min(len * i, n);
        for(int j = L[i]; j <= R[i]; ++ j) a[j] = read(), belong[j] = i, b[j] = a[j]; 
        std :: sort(a + L[i], a + R[i] + 1);
    }
    int opt, l, r, k;
    while(m --) {
        opt = read(), l = read(), r = read(), k = read();
        if(opt == 1) printf("%d\n", findkth(l, r, k));
        else upd(l, r, k);
    }
    return 0;
} 
2021/10/2 21:41
加载中...