POJ 2104 K-th Number (划分树)

                                                            K-th Number

Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 52651   Accepted: 18091
Case Time Limit: 2000MS

Description

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 segment.
That is, given an array a[1...n] of different integer numbers, your
program must answer a series of questions Q(i, j, k) in the form: "What
would be the k-th number in a[i...j] segment, if this segment was
sorted?"

For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the
question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort
this segment, we get (2, 3, 5, 6), the third number is 5, and therefore
the answer to the question is 5.

Input

The
first line of the input file contains n --- the size of the array, and m
--- the number of questions to answer (1 <= n <= 100 000, 1 <=
m <= 5 000).

The second line contains n different integer numbers not exceeding 109 by their absolute values --- the array for which the answers should be given.

The following m lines contain question descriptions, each
description consists of three numbers: i, j, and k (1 <= i <= j
<= n, 1 <= k <= j - i + 1) and represents the question Q(i, j,
k).

Output

For each question output the answer to it --- the k-th number in sorted a[i...j] segment.

Sample Input

7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3

Sample Output

5
6
3

Hint

This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.

【分析】第一道划分树,懂了一丝,继续努力。。。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define lson(x) ((x<<1))
#define rson(x) ((x<<1)+1)
using namespace std;
typedef long long ll;
const int N=1e5+50;
const int M=N*N+10;
struct P_Tree{
    int n,order[N];
    int valu[20][N],num[20][N];
    ll sum[N],lsum[20][N],isum;
    void build(int l,int r,int ind){
        if(l==r)return;
        int mid=(l+r)/2;
        int same=mid-l+1,ln=l,rn=mid+1;
        for(int i=l;i<=r;i++){
            int flag=0;
            if((valu[ind][i]<order[mid])||(valu[ind][i]==order[mid]&&same)){
                flag=1;
                valu[ind+1][ln++]=valu[ind][i];
                lsum[ind][i]=lsum[ind][i-1]+valu[ind][i];
                if(valu[ind][i]==order[mid])same--;
            }
            else {
                valu[ind+1][rn++]=valu[ind][i];
                lsum[ind][i]=lsum[ind][i-1]+valu[ind][i];
            }
            num[ind][i]=num[ind][i-1]+flag;
        }
        build(l,mid,ind+1);
        build(mid+1,r,ind+1);
    }
    void init(int len){
        n=len;sum[0]=0;
        for(int i=0;i<20;i++)valu[i][0]=num[i][0]=lsum[i][0]=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&order[i]);
            valu[0][i]=order[i];
            sum[i]=sum[i-1]+order[i];
        }
        sort(order+1,order+n+1);
        build(1,n,0);
    }
    int query(int s,int t,int k,int l,int r,int ind){
        if(l==r)return valu[ind][l];
        int mid=(l+r)/2;
        int lx=num[ind][s-1]-num[ind][l-1];
        int ly=num[ind][t]-num[ind][s-1];
        int rx=s-1-l+1-lx;
        int ry=t-s+1-ly;
        if(ly>=k)return query(l+lx,l+lx+ly-1,k,l,mid,ind+1);
        else {
            isum+=lsum[ind][t]-lsum[ind][s-1];
            s=mid+1+rx;
            t=mid+1+rx+ry-1;
            return query(s,t,k-ly,mid+1,r,ind+1);
        }
    }
}tree;
int main() {
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        tree.init(n);
        while(m--){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            printf("%d\n",tree.query(u,v,w,1,n,0));
        }
    }
}
时间: 2024-08-06 05:47:45

POJ 2104 K-th Number (划分树)的相关文章

【POJ 2104】 K-th Number 主席树模板题

达神主席树讲解传送门:http://blog.csdn.net/dad3zz/article/details/50638026 2016-02-23:真的是模板题诶,主席树模板水过.今天新校网不好,没有评测,但我立下flag这个代码一定能A.我的同学在自习课上考语文,然而机房党都跑到机房来避难了\(^o^)/~ #include<cstdio> #include<cstring> #include<algorithm> #define for1(i,a,n) for(i

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

[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 K-th Number(划分树)

题目链接:http://poj.org/problem?id=2104 题目分析:该问题给定一段区间中的值,再给定一段查询区间[ql, qr],需要给出该查询区间中的值在排序后的第K大的值: 使用划分树即可解决该问题:划分树的建树的复杂度为O(NlogN),查询一个区间的第K大值的复杂度为O(logN): 代码如下: #include <cstdio> #include <iostream> #include <algorithm> using namespace st

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

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

poj 2104 K-th Number (划分树入门)

题意:给n个数,m次询问,每次询问L到R中第k小的数是哪个 算法:划分树 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 7 const int mx=1e5+5; 8 int tree[30][mx]; 9 int sortt[mx]; 10 int sum[30][mx]; 11 12 vo

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 <c

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

杭电ACM2665——Kth number~~划分树

题目的意思:给点区间[a, b],查找第K大的数,和POJ2104题一样,只是HDU上的时间限制5000MS,用我在POJ上的方法,过不了,会超时. 而这一题的代码,改一下main函数的输入,就可以直接AC了POJ上的2104. 这题,用分桶法,WR,纠结了一晚上,最后还是放弃了,实在不知道错在哪里.于是改用了划分树的方法,学习了划分树的建立和查找. 划分树:主要运用于求解序列中区间[a, b]上的第K大的数,也就是区间[a, b]从小到大排序,第K个. 主要的算法思路是: 1,建树:先排序好存

poj2104--K-th Number(划分树)

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