先打上代码以后更新解释
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #define REP(i, s, n) for(int i = s; i <= n; i ++) 7 #define RAP(i, n, s) for(int i = n; i >= s; i --) 8 #define LOW for(; x; x -= x & (-x)) 9 using namespace std; 10 const int maxn = 100000 + 10; 11 const int Maxn = 100000; 12 const int maxnode = 200 * maxn; 13 int s[maxnode], ls[maxnode], rs[maxnode], A[maxn], root[maxn], Ln, Rn, L[maxn], R[maxn], c[maxn]; 14 int n, Q, ms = 0; 15 void update(int x, int& y, int L, int R, int pos, int v){ 16 s[y = ++ ms] = s[x] + v; 17 if(L == R) return ; 18 int M = L + R >> 1; 19 ls[y] = ls[x]; rs[y] = rs[x]; 20 if(pos <= M) update(ls[x], ls[y], L, M, pos, v); 21 else update(rs[x], rs[y], M + 1, R, pos, v); 22 return ; 23 } 24 void update(int x, int v){ 25 for(int i = x; i <= Maxn; i += i & (-i)) update(c[i], c[i], 1, Maxn, A[x], -1); A[x] = v; 26 for(int i = x; i <= Maxn; i += i & (-i)) update(c[i], c[i], 1, Maxn, A[x], 1); return ; 27 } 28 void init(int x, int tp){ 29 if(!tp) { L[++ Ln] = root[x]; LOW if(c[x]) L[++ Ln] = c[x]; } 30 else { R[++ Rn] = root[x]; LOW if(c[x]) R[++ Rn] = c[x]; } 31 return ; 32 } 33 int query(int ql, int qr, int k){ 34 Ln = Rn = 0; init(qr, 1); init(ql - 1, 0);//0是左 35 int ll = 1, rr = Maxn; 36 while(ll < rr){ 37 int Lsum = 0, Rsum = 0, M = ll + rr >> 1; 38 REP(i, 1, Ln) Lsum += s[ls[L[i]]]; 39 REP(i, 1, Rn) Rsum += s[ls[R[i]]]; 40 int kth = Rsum - Lsum; 41 if(kth >= k){//往左找 42 REP(i, 1, Ln) L[i] = ls[L[i]]; 43 REP(i, 1, Rn) R[i] = ls[R[i]]; 44 rr = M; 45 } 46 else{//往右找 47 REP(i, 1, Ln) L[i] = rs[L[i]]; 48 REP(i, 1, Rn) R[i] = rs[R[i]]; 49 ll = M + 1; k -= kth; //看好了二分! 别忘了还要减 Σ( ° △ °|||)︴ 50 } 51 } 52 return ll; 53 } 54 inline void read(int &x){ 55 x = 0; int sig = 1; char ch = getchar(); 56 while(!isdigit(ch)) { if(ch == ‘-‘) sig = -1; ch = getchar(); } 57 while(isdigit(ch)) x = 10 * x + ch - ‘0‘, ch = getchar(); 58 x *= sig; return ; 59 } 60 inline void write(int x){ 61 if(x == 0) { putchar(‘0‘); return ; } 62 if(x < 0) putchar(‘-‘), x = -x; 63 int len = 0, buf[20]; 64 while(x) buf[len ++] = x % 10, x /= 10; 65 RAP(i, len - 1, 0) putchar(buf[i] + ‘0‘); return ; 66 } 67 void init(){ 68 read(n); read(Q); 69 REP(i, 1, n) read(A[i]); 70 REP(i, 1, n) update(root[i - 1], root[i], 1, Maxn, A[i], 1); 71 return ; 72 } 73 void work(){ 74 int tp, ql, qr, k, x, v; 75 while(Q --){ 76 read(tp); 77 if(tp) read(ql), read(qr), read(k), write(query(ql, qr, k) - 1), putchar(‘\n‘);// 减一 78 else read(x), read(v), update(x, v); 79 } 80 return ; 81 } 82 void print(){ 83 84 return ; 85 } 86 int main(){ 87 init(); 88 work(); 89 print(); 90 return 0; 91 }
时间: 2024-10-08 22:09:12