zoukankan      html  css  js  c++  java
  • bzoj1901: Zju2112 Dynamic Rankings

    题目链接

    bzoj1901: Zju2112 Dynamic Rankings

    题解

    带修改主席树
    只需要在外面套一层BIT
    原先的主席树是一串前缀,现在把这个前缀换成bit就是了
    建树复杂度是nlog^2n的
    对于这题可以只用bit维护修改的内容,开始只需要建常规主席树就好
    这样建树的复杂度是nlogn的

    代码

    #include<cstdio> 
    #include<algorithm> 
     
    #define ls(x) t[x].lc
    #define rs(x) t[x].rc
    typedef long long ll;
    const int maxn = 20007; 
    inline int read() {
         int x = 0,f = 1; 
         char c = getchar(); 
         while(c < '0' || c > '9') c = getchar(); 
         while(c <= '9' && c >= '0')x = x * 10 + c - '0',c = getchar(); 
         return x * f; 
    } 
    #define lowbit(x) (x & -x) 
    int n,Q,m,a[maxn],mp[maxn];  
    char s[20];  
    struct Que{  
        int type,i,j,k,x,d; 
    } q[maxn];  
    inline int bin(int v) { 
        int l = 1,r = m ; 
        while(l <= r) { 
            int mid = l + r >> 1;
            if(mp[mid] == v) return mid;
            if(mp[mid] > v) r = mid - 1; 
            else l = mid + 1;   
        } 
        return - 1; 
    } 
      
    struct node { 
        int lc,rc,w; 
    }t[maxn * 100]; 
    int sz = 0,root[maxn],rt[maxn]; 
    void insert(int &x,int l,int r,int num,int v) { 
        t[++sz] = t[x];x = sz; 
        t[x].w += v; 
        if(l == r) return; 
        int mid = (l + r) >> 1; 
        if(num <= mid) insert(t[x].lc,l,mid,num,v); 
        else insert(t[x].rc,mid + 1,r,num,v); 
    } 
    void add(int p,int v) { 
        int tmp = bin(a[p]); 
        for(int i = p;i <= n;i += lowbit(i)) insert(root[i],1,m,tmp,v); 
    }  
    int q1[maxn],t1,q2[maxn],t2; 
    int cal() {  
        int sum1 = 0,sum2 = 0; 
        for(int i = 1;i <= t1;i ++) sum1 += t[ls(q1[i])].w; 
        for(int i = 1;i <= t2;i ++) sum2 += t[ls(q2[i])].w; 
        return sum2 - sum1; 
    } 
    int query(int ql,int qr,int k) {  
        int l = 1,r = m;t1 = t2 = 0; 
        for(int i = ql - 1;i;i -= lowbit(i)) q1[++ t1] = root[i]; 
        for(int i = qr;i;i -= lowbit(i)) q2[++ t2] = root[i]; 
        ql --;
        ql = rt[ql]; qr = rt[qr];
        while(l < r) { 
            int lsiz = cal() + t[ls(qr)].w - t[ls(ql)].w,mid = (l + r) >> 1; 
            if(k <= lsiz) { 
                for(int i = 1;i <= t1;++ i) q1[i] = t[q1[i]].lc; 
                for(int i = 1;i <= t2;++ i) q2[i] = t[q2[i]].lc; 
                ql = ls(ql);qr = ls(qr); 
                r = mid; 
            }else { 
                for(int i = 1;i <= t1;++ i) q1[i] = t[q1[i]].rc; 
                for(int i = 1;i <= t2;++ i) q2[i] = t[q2[i]].rc; 
                ql = rs(ql);qr = rs(qr); 
                l = mid + 1;k -= lsiz ; 
            } 
        } 
        return l; 
    } 
    int main() { 
        n = read(), Q = read(); 
        char s[10]; 
        for(int i = 1;i <= n;i ++) a[i] = mp[++ m] = read(); 
        for(int i = 1;i <= Q ;i ++) {  
            scanf("%s",s + 1); 
            if(s[1] == 'Q') q[i].type = 0,q[i].i = read(),q[i].j = read(),q[i].k = read(); 
            else q[i].type = 1, q[i].x = read(),q[i].d = mp[++ m] = read(); 
        } 
        std::sort(mp + 1,mp + m + 1); 
        int p = 1; for(int i = 2;i <= m;i ++) if(mp[i] != mp[i - 1]) mp[++ p] = mp[i]; m = p; 
        for(int i = 1;i <= n;i ++) rt[i] = rt[i-1],insert(rt[i],1,m,bin(a[i]),1); //这里直接建主席树就好了 
        for(int i = 1;i <= Q;i ++) {  
            if(q[i].type == 0) {  
                printf("%d
    ",mp[query(q[i].i,q[i].j,q[i].k)]);  
            } else {  
                add(q[i].x,-1);  
                a[q[i].x] = q[i].d;  
                add(q[i].x,1); 
            } 
        } 
        return 0; 
    }  0
    
  • 相关阅读:
    流的概念(转自本站progor)
    Centos7安装OpenLDAP
    python发送post请求
    小计安装部署滴滴开源kafkamanager工具
    VSCode集成Cmder控制台输入中文乱码
    在win10的pycharm使用wsl中的python进行开发
    《Python数据科学手册》学习笔记及书评
    VSCode小说插件ReadNovel根据内容查找页码
    《TensorFlow实战Google深度学习框架(第二版)》学习笔记及书评
    Cmder启动WSL中的Ubuntu出现复制粘贴异常
  • 原文地址:https://www.cnblogs.com/sssy/p/9503611.html
Copyright © 2011-2022 走看看