zoukankan      html  css  js  c++  java
  • 主席树套树状数组 动态区间第k小

    先打上代码以后更新解释

     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('
    ');// 减一 
    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 }

     逗比版:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define t node[d]
     6 #define cnt countn[d]
     7 #define repnode(d) for(int i=1;i<=countn[d];i++)
     8 using namespace std;
     9 const int maxn=100000+10,maxnode=20000000+10,Max=100000;
    10 int ls[maxnode],rs[maxnode],s[maxnode],root[maxn],A[maxn],c[maxn],n,m,ms=0,countn[2],node[2][maxn],sum[2];
    11 void update(int x,int& y,int L,int R,int pos,int d){
    12     s[y=++ms]=s[x]+d;
    13     if(L==R) return;
    14     ls[y]=ls[x];rs[y]=rs[x];
    15     int M=L+R>>1;
    16     if(pos<=M) update(ls[x],ls[y],L,M,pos,d);
    17     else update(rs[x],rs[y],M+1,R,pos,d);
    18     return;
    19 }
    20 void update(int x,int v){
    21     for(int i=x;i<=Max;i+=i&-i) update(c[i],c[i],1,Max,A[x],-1);A[x]=v;
    22     for(int i=x;i<=Max;i+=i&-i) update(c[i],c[i],1,Max,A[x],1);return;
    23 }
    24 void init(int x,int d){
    25     t[++cnt]=root[x];
    26     for(;x;x-=x&-x) if(c[x]) t[++cnt]=c[x];
    27     return;
    28 }
    29 int query(int ql,int qr,int k){
    30     countn[0]=countn[1]=0;
    31     init(qr,1);init(ql-1,0);
    32     int L=1,R=Max,d;
    33     while(L<R){
    34         sum[0]=sum[1]=0;
    35         int M=L+R>>1;
    36         repnode(d=0) sum[d]+=s[ls[t[i]]];
    37         repnode(d=1) sum[d]+=s[ls[t[i]]];
    38         int kth=sum[1]-sum[0];
    39         if(k<=kth){
    40             repnode(d=0) t[i]=ls[t[i]];
    41             repnode(d=1) t[i]=ls[t[i]];
    42             R=M;
    43         }
    44         else{
    45             repnode(d=0) t[i]=rs[t[i]];
    46             repnode(d=1) t[i]=rs[t[i]];
    47             L=M+1;k-=kth;
    48         }
    49     } return L;
    50 }
    51 inline int read(){
    52     int x=0,sig=1;char ch=getchar();
    53     while(!isdigit(ch)){if(ch=='-') sig=-1;ch=getchar();}
    54     while(isdigit(ch)) x=10*x+ch-'0',ch=getchar();
    55     return x*=sig;
    56 }
    57 inline void write(int x){
    58     if(x==0){putchar('0');return;} if(x<0) putchar('-'),x=-x;
    59     int len=0,buf[15]; while(x) buf[len++]=x%10,x/=10;
    60     for(int i=len-1;i>=0;i--) putchar(buf[i]+'0');return;
    61 }
    62 void init(){
    63     n=read();m=read();
    64     for(int i=1;i<=n;i++) A[i]=read();
    65     for(int i=1;i<=n;i++) update(root[i-1],root[i],1,Max,A[i],1);
    66     return;
    67 }
    68 void work(){
    69     int tp,i,j,k,x,v;
    70     while(m--){
    71         tp=read();
    72         if(tp){
    73             i=read();j=read();k=read();
    74             write(query(i,j,k)-1);putchar('
    ');
    75         }
    76         else{
    77             x=read();v=read();
    78             update(x,v);
    79         }
    80     }
    81     return;
    82 }
    83 void print(){
    84     return;
    85 }
    86 int main(){
    87     init();work();print();return 0;
    88 }
  • 相关阅读:
    PAT (Advanced Level) 1010. Radix (25)
    PAT (Advanced Level) 1009. Product of Polynomials (25)
    PAT (Advanced Level) 1008. Elevator (20)
    PAT (Advanced Level) 1007. Maximum Subsequence Sum (25)
    PAT (Advanced Level) 1006. Sign In and Sign Out (25)
    PAT (Advanced Level) 1005. Spell It Right (20)
    PAT (Advanced Level) 1004. Counting Leaves (30)
    PAT (Advanced Level) 1001. A+B Format (20)
    PAT (Advanced Level) 1002. A+B for Polynomials (25)
    PAT (Advanced Level) 1003. Emergency (25)
  • 原文地址:https://www.cnblogs.com/chxer/p/4427235.html
Copyright © 2011-2022 走看看