zoukankan      html  css  js  c++  java
  • [Luogu] 可持久化线段树 1(主席树)

    https://www.luogu.org/problemnew/show/P3834

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    
    using namespace std;
    const int maxn = 2e5 + 10;
    
    #define RR freopen("gg.in", "r", stdin)
    
    int n, m;
    int cnt;
    
    struct node {
        int L, R;//分别指向左右子树
        int sum;//该节点对应区间数的个数
        node() {
            sum = 0;
        }
    } Tree[maxn * 20];
    
    struct value {
        int x;//值的大小
        int id;//离散之前在原数组中的位置
    } Value[maxn];
    
    bool cmp(value v1, value v2) {
        return v1.x < v2.x;
    }
    
    int root[maxn];//多颗线段树的根节点
    int rank[maxn];//原数组离散之后的数组
    
    void init() {
        cnt = 1;
        root[0] = 0;
        Tree[0].L = Tree[0].R = Tree[0].sum = 0;
    }
    
    void update(int num, int &rt, int l, int r) {
        Tree[cnt++] = Tree[rt];//bu存在Tree[0] 
        rt = cnt - 1;
        Tree[rt].sum++;
        if(l == r) return;
        int mid = (l + r)>>1;
        if(num <= mid) update(num, Tree[rt].L, l, mid);
        else update(num, Tree[rt].R, mid + 1, r);
    }
    
    int query(int i, int j, int k, int l, int r) {
        int d = Tree[Tree[j].L].sum - Tree[Tree[i].L].sum;
        if(l == r) return l;
        int mid = (l + r)>>1;
        if(k <= d) return query(Tree[i].L, Tree[j].L, k, l, mid);
        else return query(Tree[i].R, Tree[j].R, k - d, mid + 1, r);
    }
    
    int main() {
        RR;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &Value[i].x);
            Value[i].id = i;
        }
        //进行离散化
        sort(Value + 1, Value + n + 1, cmp);
        for(int i = 1; i <= n; i++) rank[Value[i].id] = i;
        init();
        for(int i = 1; i <= n; i++) {
            root[i] = root[i - 1];
        //    cout << root[i] << endl;
            update(rank[i], root[i], 1, n);//update(第i个数的排名,)
        }
        int left, right, k;
        for(int i = 1; i <= m; i++) {
            scanf("%d%d%d", &left, &right, &k);
            printf("%d
    ", Value[query(root[left - 1], root[right], k, 1, n)].x);
        }
        return 0;
    }
  • 相关阅读:
    安装部署Python开发环境
    CentOS系统常见优化
    chm文件打开无法显示
    数据库恢复技术
    视图的认识
    存储过程的认识
    error C2471: 无法更新程序数据库 ,fatal error C1083: 无法打开程序数据库文件
    ubuntu下使用aptget install下载安装文件管理
    转:[译文] 程序员的禅修之路
    数据库的两段锁协议
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8454003.html
Copyright © 2011-2022 走看看