• Bzoj 3196 二逼平衡树


    树状数组套线段树(值域线段树)记得离散化

    # include <bits/stdc++.h>
    # define IL inline
    # define RG register
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(2e5 + 10), __(5e6 + 10), INF(2147483647);
    
    IL ll Read(){
        RG char c = getchar(); RG ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int n, m, qo[_], ql[_], qr[_], qk[_], len, o[_], a[_];
    int sz[__], ls[__], rs[__], rt[__], tmp[2][20], cnt, t0, t1;
    
    IL void Modify(RG int &x, RG int l, RG int r, RG int id, RG int v){
        if(!x) x = ++cnt; sz[x] += v;
        if(l == r) return;
        RG int mid = (l + r) >> 1;
        if(id <= mid) Modify(ls[x], l, mid, id, v);
        else Modify(rs[x], mid + 1, r, id, v);
    }
    
    IL void Add(RG int x, RG int v){  for(RG int i = x; i <= n; i += i & -i) Modify(rt[i], 1, len, a[x], v);  }
    
    IL int Query(RG int x, RG int l, RG int r, RG int id){
        if(l == r) return sz[x];
        RG int mid = (l + r) >> 1;
        if(id <= mid) return Query(ls[x], l, mid, id);
        else return sz[ls[x]] + Query(rs[x], mid + 1, r, id);
    }
    
    IL int Rank(RG int l, RG int r, RG int k){
        if(l > r) return 0;
        RG int sum = 0;
        for(RG int i = r; i; i -= i & -i) sum += Query(rt[i], 1, len, k);
        for(RG int i = l - 1; i; i -= i & -i) sum -= Query(rt[i], 1, len, k);
        return sum;
    }
    
    IL int Find_Kth(RG int l, RG int r, RG int k){
        if(l == r) return l;
        RG int mid = (l + r) >> 1, sum = 0;
        for(RG int i = 1; i <= t1; ++i) sum += sz[ls[tmp[1][i]]];
        for(RG int i = 1; i <= t0; ++i) sum -= sz[ls[tmp[0][i]]];
        if(sum >= k){
            for(RG int i = 1; i <= t1; ++i) tmp[1][i] = ls[tmp[1][i]];
            for(RG int i = 1; i <= t0; ++i) tmp[0][i] = ls[tmp[0][i]];
            return Find_Kth(l, mid, k);
        }
        else{
            for(RG int i = 1; i <= t1; ++i) tmp[1][i] = rs[tmp[1][i]];
            for(RG int i = 1; i <= t0; ++i) tmp[0][i] = rs[tmp[0][i]];
            return Find_Kth(mid + 1, r, k - sum);
        }
    }
    
    IL int Kth(RG int l, RG int r, RG int k){
        t0 = t1 = 0;
        for(RG int i = l - 1; i; i -= i & -i) tmp[0][++t0] = rt[i];
        for(RG int i = r; i; i -= i & -i) tmp[1][++t1] = rt[i];
        return o[Find_Kth(1, len, k)];
    }
    
    int main(RG int argc, RG char* argv[]){
        n = Read(); m = Read();
        for(RG int i = 1; i <= n; ++i) a[i] = Read(), o[++len] = a[i];
        for(RG int i = 1; i <= m; ++i){
            qo[i] = Read();
            if(qo[i] == 3) ql[i] = qr[i] = Read(), qk[i] = Read();
            else ql[i] = Read(), qr[i] = Read(), qk[i] = Read();
            if(qo[i] != 2) o[++len] = qk[i];
        }
        sort(o + 1, o + len + 1); len = unique(o + 1, o + len + 1) - o - 1;
        for(RG int i = 1; i <= n; ++i) a[i] = lower_bound(o + 1, o + len + 1, a[i]) - o, Add(i, 1);
        for(RG int i = 1; i <= m; ++i){
            if(qo[i] == 3){
                Add(ql[i], -1);
                a[ql[i]] = lower_bound(o + 1, o + len + 1, qk[i]) - o;
                Add(ql[i], 1);
            }
            else if(qo[i] == 1){
                qk[i] = lower_bound(o + 1, o + len + 1, qk[i]) - o;
                printf("%d
    ", Rank(ql[i], qr[i], qk[i] - 1) + 1);
            }
            else if(qo[i] == 2) printf("%d
    ", Kth(ql[i], qr[i], qk[i]));
            else if(qo[i] == 4){
                qk[i] = lower_bound(o + 1, o + len + 1, qk[i]) - o;
                RG int sum = Rank(ql[i], qr[i], qk[i] - 1);
                printf("%d
    ", Kth(ql[i], qr[i], sum));
            }
            else{
                qk[i] = lower_bound(o + 1, o + len + 1, qk[i]) - o;
                RG int sum = Rank(ql[i], qr[i], qk[i]);
                printf("%d
    ", Kth(ql[i], qr[i], sum + 1));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    TypeError: 'ExcelData' object is not iterable
    输出重定向
    联想Thinkpad T450 屏幕更换记录
    C-sysytem命令的使用
    CMD命令大全
    Ubuntu16.04 添加 Docker用户组
    Docker学习
    Linux系统卡死后紧急处理
    Django之ModelForm详解
    Django的ORM实现数据库事务操作
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206312.html
Copyright © 2020-2023  润新知