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;
    }
  • 相关阅读:
    FAQ接口自动化_转载参考
    FAQ接口自动化_报错解决
    SpringBootRESTfulAPI平台项目-演示版01
    SpringBoot08_mysql操作
    SpringBoot07_RESTful API:获取girls表的内容
    SpringBoot06_程序自动化创建/更新数据库里的表信息
    mysqldump
    js 原型链
    node.js 事件发射器模式
    codeblocks 支持c++11
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8454003.html
Copyright © 2011-2022 走看看