hdu 2665 Kth number (poj 2104 K-th Number) 划分树

划分树的基本功能是,对一个给定的数组,求区间[l,r]内的第k大(小)数。

划分树的基本思想是分治,每次查询复杂度为O(log(n)),n是数组规模。

具体原理见http://baike.baidu.com/link?url=vIUKtsKYx7byeS2KCOHUI14bt_0sdHAa9BA1VceHdGsTv5jVq36SfZgBKdaHYUGqIGvIGrE_aJtqy0D0b1fCoq

个人感觉看代码是最好的学习方法。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 100100

int a[N];
int s[30][N];//划分树
int num[30][N];//num[i][j] - num[i][j-1] == 1表示第i层第j个数在下层中要被划入左子树

void build(int l, int r, int dep = 1)
{
    if(l == r){
        s[dep][l] = s[dep-1][l];
        return;
    }
    int mid = l+r>>1;
    int cnt = mid-l+1;
    for(int i = l; i <= r; i++) if(s[dep-1][i] < a[mid]) cnt--;
    int c1 = l, c2 = mid+1;
    for(int i = l; i <= r; i++)
    {
        if(s[dep-1][i] < a[mid] || ( s[dep-1][i] == a[mid] && cnt-- > 0)) s[dep][c1++] = s[dep-1][i];
        else s[dep][c2++] = s[dep-1][i];

        num[dep-1][i] = num[dep-1][l-1]+c1-l;
    }
    build(l, mid, dep+1);
    build(mid+1, r, dep+1);
}

int query(int l, int r, int k, int L, int R, int dep = 0)
{
    if(l == r) return s[dep][l];
    int mid = L+R>>1;
    int cnt = num[dep][r] - num[dep][l-1];

    if(cnt >= k)
    {
        int nl = L+num[dep][l-1]-num[dep][L-1];
        int nr = nl+cnt-1;
        return query(nl, nr, k, L, mid, dep+1);
    }
    else
    {
        int nr = r+num[dep][R]-num[dep][r];
        int nl = nr - (r-l-cnt);
        return query(nl, nr, k-cnt, mid+1, R, dep+1);
    }
}

int main()
{
    int T, n, m;
    scanf("%d", &T);
    while(T--)
    //while(~scanf("%d %d", &n, &m))
    {
        memset(num, 0, sizeof(num));
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        for(int i = 1; i <= n; i++) s[0][i] = a[i];
        sort(a+1, a+n+1);
        build(1, n);
        for(int i = 0; i < m; i++)
        {
            int l, r, k;
            scanf("%d %d %d", &l, &r, &k);
            printf("%d\n", query(l, r, k, 1, n));
        }

    }
    return 0;
}
时间: 2024-10-05 11:34:50

hdu 2665 Kth number (poj 2104 K-th Number) 划分树的相关文章

hdu 2665 Kth number(划分树)

Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4602 Accepted Submission(s): 1468 Problem Description Give you a sequence and ask you the kth big number of a inteval. Input The first l

K-th Number POJ - 2104 (整体二分)

K-th Number POJ - 2104 之前学主席树写了一遍 最近再看CDQ分治和整体二分,一直不是很理解,看着别人代码稍微理解了一些 1 //比主席树慢了挺多 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 6 using namespace std; 7 8 const int maxn = 1e5 + 10; 9 const int maxq = 5010; 10 const

[NBUT 1458 Teemo]区间第k大问题,划分树

裸的区间第k大问题,划分树搞起. #pragma comment(linker, "/STACK:10240000") #include <map> #include <set> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <vector> #inc

POJ 2104&amp;HDU 2665 Kth number(主席树入门+离散化)

K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 50247   Accepted: 17101 Case Time Limit: 2000MS Description You are working for Macrohard company in data structures department. After failing your previous task about key inse

K-th Number POJ - 2104 划分树

K-th Number You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array

hdu 2665 Kth number(划分树)

题意:给定一列数,每次查询区间[s,t]中的第k大: 参考:http://www.cnblogs.com/kane0526/archive/2013/04/20/3033212.html http://www.cnblogs.com/kuangbin/archive/2012/08/14/2638829.html 思路:快排思想+线段树=划分树,也就是树的每一层都按规则划分: 对于本题,建树前,保存原数列排序后的数列,原数列作为树的顶层: 建树时,考虑当前区间中的中间值,若大于中间值,在下一层中

POJ 2104 区间第K大值(划分树做法)

由于深感自己水平低下,把大部分有效时间放在了刷题上,于是好久没写题解了.今天刚学了下划分树的原理,于是写道简单题练练手. 题目链接:http://poj.org/problem?id=2104 划分树的空间复杂度和时间复杂度均为O(nlogn),对于解决该问题而言,每次查询的复杂度为O(logn),比归并树O((log)^3)节省时间[归并树采用了三次二分]. 但是划分树也有自己的缺点,不支持更新以及适用范围狭窄,总之...是时代的眼泪了= = AC代码: #include <iostream>

POJ 2761-Feed the dogs(划分树)求区间内第k小的数

Feed the dogs Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 17679   Accepted: 5561 Description Wind loves pretty dogs very much, and she has n pet dogs. So Jiajia has to feed the dogs every day for Wind. Jiajia loves Wind, but not the

HDU 2665.Kth number 区间第K小

Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11394    Accepted Submission(s): 3465 Problem Description Give you a sequence and ask you the kth big number of a inteval. Input The f