zoukankan      html  css  js  c++  java
  • 划分树

    POJ 2214  裸的划分树求区间第k大值

    //POJ 2104
    
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #define maxn 100010
    using namespace std;
    
    int tree[30][maxn];
    int sorted[maxn];
    int toleft[30][maxn];
    
    void build(int l, int r, int dep) {
        if (l == r) return;
        int mid = (l+r) >> 1;
        int same = mid - l + 1;
        for (int i=l; i<=r; ++i)
            if (tree[dep][i] < sorted[mid])
            same--;
        int lpos = l;
        int rpos = mid+1;
        for (int i=l; i<=r; ++i) {
            if (tree[dep][i] < sorted[mid])
                tree[dep+1][lpos++] = tree[dep][i];
            else if (tree[dep][i] == sorted[mid] && same>0) {
                tree[dep+1][lpos++] = tree[dep][i];
                same--;
            }else tree[dep+1][rpos++] = tree[dep][i];
            toleft[dep][i] = toleft[dep][l-1]+lpos-l;
        }
        build(l, mid, dep+1);
        build(mid+1, r, dep+1);
    }
    
    int query(int L, int R, int l, int r, int dep, int k) {
        if (l == r) return tree[dep][l];
        int mid = (L+R)>>1;
        int cnt = toleft[dep][r] - toleft[dep][l-1];
        if (cnt >= k) {
            int newl = L+toleft[dep][l-1]-toleft[dep][L-1];
            int newr = newl+cnt-1;
            return query(L, mid, newl, newr, dep+1, k);
        }else {
            int newr = r+toleft[dep][R]-toleft[dep][r];
            int newl = newr-(r-l-cnt);
            return query(mid+1, R, newl, newr, dep+1, k-cnt);
        }
    }
    
    
    int main() {
       // freopen("in.cpp", "r", stdin);
        int n, m;
        while(~scanf("%d%d", &n, &m)) {
            for (int i=1; i<=n; ++i) {
                scanf("%d", &tree[0][i]);
                sorted[i] = tree[0][i];
            }
            sort(sorted+1, sorted+1+n);
            build(1, n, 0);
            while(m--) {
                int a, b, c;
                scanf("%d%d%d", &a, &b, &c);
                printf("%d
    ", query(1, n, a, b, 0, c));
            }
        }
        return 0;
    }
    

    HDU 4417 二分+划分树

    //HDU 4417
    
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    
    const int maxn = 1e5+10;
    
    int tree[30][maxn];
    int toleft[30][maxn];
    int sorted[maxn];
    
    void build(int l, int r, int dep) {
        if (l == r) return;
        int mid = (l+r) >> 1;
        int same = mid - l + 1;
        for (int i=l; i<=r; ++i)
            if (tree[dep][i] < sorted[mid])
            same--;
        int lpos = l;
        int rpos = mid+1;
        for (int i=l; i<=r; ++i) {
            if (tree[dep][i] < sorted[mid])
                tree[dep+1][lpos++] = tree[dep][i];
            else if (tree[dep][i] == sorted[mid] && same>0) {
                tree[dep+1][lpos++] = tree[dep][i];
                same--;
            }else tree[dep+1][rpos++] = tree[dep][i];
            toleft[dep][i] = toleft[dep][l-1]+lpos-l;
        }
        build(l, mid, dep+1);
        build(mid+1, r, dep+1);
    }
    
    int query(int L, int R, int l, int r, int dep, int k) {
        if (l == r) return tree[dep][l];
        int mid = (L+R)>>1;
        int cnt = toleft[dep][r] - toleft[dep][l-1];
        if (cnt >= k) {
            int newl = L+toleft[dep][l-1]-toleft[dep][L-1];
            int newr = newl+cnt-1;
            return query(L, mid, newl, newr, dep+1, k);
        }else {
            int newr = r+toleft[dep][R]-toleft[dep][r];
            int newl = newr-(r-l-cnt);
            return query(mid+1, R, newl, newr, dep+1, k-cnt);
        }
    }
    
    int solve(int n, int a, int b, int c) {
        int ans = 0;
        int l = 1;
        int r = b - a + 1;
        int mid;
        while(l<=r) {
            mid = (l+r)>>1;
            int temp = query(1, n, a, b, 0, mid);
            if (temp <= c) {
                l = mid+1;
                ans = mid;
            }else r = mid - 1;
        }
        return ans;
    }
    
    
    int main() {
       // freopen("in.cpp", "r", stdin);
        int t;
        int k = 0;
        scanf("%d", &t);
        while(t--) {
            int n, m;
            scanf("%d%d", &n, &m);
            memset(toleft, 0, sizeof(toleft));
            memset(tree, 0, sizeof(tree));
    
            for (int i=1; i<=n; ++i) {
                scanf("%d", &tree[0][i]);
                sorted[i] = tree[0][i];
            }
            sort(sorted+1, sorted+1+n);
            build(1, n, 0);
            printf("Case %d:
    ", ++k);
            for (int i=0; i<m; ++i) {
                int a, b, c;
                scanf("%d%d%d",&a, &b, &c);
                a++;
                b++;
                int ans = solve(n, a, b, c);
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    房子不是盖来住的
    房子不是盖来住的
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5929280.html
Copyright © 2011-2022 走看看