主席樹模板

來源:互聯網
上載者:User

標籤:演算法   資料結構   

用這個模板可以直接A掉 HDU 2665 Kth number 這題了!


/*  主席樹求區間第K大模板: *      模板特殊說明: *          每棵樹是維護從1開始到cnt的下標資訊 */#include <stdio.h>#include <algorithm>#define maxn 100010using namespace std;int T, n, m, tot, a[maxn], b[maxn], cnt;    //T為輸入cas組數,n為原數列數組個數,m為詢問個數,tot為建樹時新節點    //a為原數列,b為用來離散化的數列,其unique後元素個數為cntstruct N { int ls, rs, w; } tree[30 * maxn];    //ls為左兒子節點下標,rs為右兒子節點下標,w為此區間內元素數量int roots[maxn];    //roots記錄每棵樹的根節點下標int build_tree(int l, int r) {  //先建造一棵空樹    int newnode = tot++;    tree[newnode].w = 0;    if (l != r) {        int mid = (l + r) / 2;        tree[newnode].ls = build_tree(l, mid);        tree[newnode].rs = build_tree(mid + 1, r);    }    return newnode;}int updata(int rt, int pos, int val) {  //rt為根節點,在pos位置上加val的值    int newnode = tot++, tmp = newnode;    tree[newnode].w = tree[rt].w + val;    int l = 1, r = cnt;    while (l < r) {        int mid = (l + r) / 2;        if (pos <= mid) {            tree[newnode].ls = tot++;            tree[newnode].rs = tree[rt].rs;            newnode = tree[newnode].ls;            rt = tree[rt].ls;            r = mid;        }        else {            tree[newnode].ls = tree[rt].ls;            tree[newnode].rs = tot++;            newnode = tree[newnode].rs;            rt = tree[rt].rs;            l = mid + 1;        }        tree[newnode].w = tree[rt].w + val;    }    return tmp;}int query(int rt1, int rt2, int k) {  //詢問根節點分別為rt1,rt2兩棵樹之間第k大的值    int l = 1, r = cnt;    while (l < r) {        int mid = (l + r) / 2;        int tmp = tree[tree[rt2].ls].w - tree[tree[rt1].ls].w;        if (tmp >= k) {            rt1 = tree[rt1].ls;            rt2 = tree[rt2].ls;            r = mid;        }        else {            k -= tmp;            rt1 = tree[rt1].rs;            rt2 = tree[rt2].rs;            l = mid + 1;        }    }    return l;}int main() {    //freopen("in.in", "r", stdin);    //freopen("out.out", "w", stdout);    scanf("%d", &T);    while (T--) {   //讀入資料群組數        scanf("%d%d", &n, &m);        for (int i = 1; i <= n; i++) {            scanf("%d", &a[i]);            b[i - 1] = a[i];        }        sort(b, b + n);        cnt = unique(b, b + n) - b;     //離散化        tot = 0;        roots[0] = build_tree(1, cnt);        for (int i = 1; i <= n; i++) {            int tmp = (int)(lower_bound(b, b + cnt, a[i]) - b) + 1;            roots[i] = updata(roots[i - 1], tmp, 1);    //在上一次的基礎上建樹        }        int l,r,k;        for(int i=0;i<m;i++){            scanf("%d %d %d",&l,&r,&k); //讀入求l和r區間第k大的數            int tmp = query(roots[l-1],roots[r],k);            printf("%d\n",b[tmp - 1]);        }    }    return 0;}


著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

主席樹模板

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.