首页 > 代码库 > poj 2104 K-th Number(划分树模板)

poj 2104 K-th Number(划分树模板)

          划分树模板题,敲上模板就ok了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define MP make_pair
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))

using namespace std;

#define MID ((l+r)>>1)

const int maxn = 100100;
const int INF = 0x3f3f3f3f;

struct KthNumber
{
    int a[maxn], s[maxn], t[20][maxn], num[20][maxn];

    void init(int n)
    {
        for(int i = 1; i <= n; i ++)
        {
            scanf("%d", &a[i]);
            s[i] = t[0][i] = a[i];
        }
        sort(s+1, s+n+1);
    }

    void Build(int c, int l, int r)
    {
        int lm = MID-l+1, lp = l, rp = MID+1;
        for(int i = l; i <= MID; i ++)
            lm -= s[i] < s[MID];
        for(int i = l; i <= r; i ++)
        {
            if(i == l) num[c][i] = 0;
            else num[c][i] = num[c][i - 1];

            if(t[c][i] == s[MID])
            {
                if(lm)
                {
                    lm --; num[c][i] ++;
                    t[c+1][lp++] = t[c][i];
                }
                else t[c+1][rp++] = t[c][i];
            }
            else if(t[c][i] < s[MID])
            {
                num[c][i] ++;
                t[c+1][lp++] = t[c][i];
            }
            else t[c+1][rp++] = t[c][i];
        }
        if(l<r)
            Build(c+1, l, MID), Build(c+1, MID+1, r);
    }

    int Query(int c, int l, int r, int ql, int qr, int k)
    {
        if(l == r) return t[c][l];
        int s, ss;
        if(l == ql) s = 0, ss = num[c][qr];
        else s = num[c][ql-1], ss = num[c][qr]-num[c][ql-1];
        if(k <= ss) return Query(c+1, l, MID, l+s, l+s+ss-1, k);
        else return Query(c+1, MID+1, r, MID+1+ql-l-s, MID+1+qr-l-s-ss, k-ss);
    }
}sol;

int main()
{
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        sol.init(n);
        sol.Build(0, 1, n);
        while(m --)
        {
            int l, r, k;
            scanf("%d%d%d", &l, &r, &k);
            printf("%d\n", sol.Query(0, 1, n, l, r, k));
        }
    }
}