PKU-2104-K-th Number

K-th Number

Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 36045   Accepted: 11522
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.

Source

Northeastern Europe 2004, Northern Subregion

这道题貌似有很多种解法

我是用归并树做的

所谓归并树就是将 归并排序过程组成一个树

树上的每个节点就是非递减的。

以1 5 2 6 3 7为例:

把归并排序递归过程记录下来即是一棵归并树:

[1 2 3 5 6 7]

[1 2 5]      [3 6 7]

[1 5] [2]    [3 6] [7]

[1][5]         [6][3]

用对应的下标区间建线段树:(这里下标区间对应的是原数列)

[1 6]

[1 3]      [4 6]

[1 2] [3]   [4 5][6]

[1][2]      [4][5]

做法就是在归并树的根节点二分查找答案,然后用线段树查询rank值,因为线段树的每个节点与归并树的节点是一一对应的,而归并树的的节点元素是非递减的,因此可以用二分算出rank值。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 100000+10;

struct node{
    int lson,rson;
    int mid(){
        return (lson+rson)>>1;
    }
}tree[maxn*4];

int seg[25][maxn];
int n,m;
int num[maxn];
int sta,ed;

void build(int L,int R,int rt,int deep){
    tree[rt].lson = L;
    tree[rt].rson = R;
    if(L==R){
        seg[deep][L] = num[L];
        return;
    }
    int mid = tree[rt].mid();
    build(L,mid,rt<<1,deep+1);
    build(mid+1,R,rt<<1|1,deep+1);
    int i = L,j = mid+1,k = L;
    while(i <= mid && j <= R){
        if(seg[deep+1][i] < seg[deep+1][j]){
            seg[deep][k] = seg[deep+1][i];
            i++;
        }else{
            seg[deep][k] = seg[deep+1][j];
            j++;
        }
        k++;
    }
    while(i <= mid){
        seg[deep][k] = seg[deep+1][i];
        i++;
        k++;
    }
    while(j <= R){
        seg[deep][k] = seg[deep+1][j];
        j++;
        k++;
    }
    return;
}

int query(int rt,int dep,int key){
    if(tree[rt].lson >= sta && tree[rt].rson <= ed){
        int t = lower_bound(&seg[dep][tree[rt].lson],&seg[dep][tree[rt].rson]+1,key)-&seg[dep][tree[rt].lson];
        return t;
    }
    int mid = tree[rt].mid();
    int  res = 0;
    if(mid >= sta){
        res += query(rt<<1,dep+1,key);
    }
    if(mid < ed){
        res += query(rt<<1|1,dep+1,key);
    }
    return res;
}

int binary(int tk){
    int L = 1,R = n;
    while(L <= R){
        int mid = (L+R) >> 1;
        if(query(1,0,seg[0][mid]) > tk){
            R = mid-1;
        }else{
            L = mid+1;
        }
    }
    if(query(1,0,seg[0][R])==tk){
        return seg[0][R];
    }else{
        return seg[0][L];
    }
}

int main(){

    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        scanf("%d",&num[i]);
    }
    build(1,n,1,0);
    while(m--){
        int k;
        scanf("%d%d%d",&sta,&ed,&k);
        printf("%d\n",binary(k-1));
    }
    return 0;
}

PKU-2104-K-th Number

时间: 2024-08-05 18:38:21

PKU-2104-K-th Number的相关文章

POJ 2104:K-th Number(主席树静态区间k大)

题目大意:对于一个序列,每次询问区间[l,r]的第k大树. 分析: 主席树模板题 program kthtree; type point=record l,r,s:longint; end; var t:array[0..100000*50]of point; a,b,id,root:array[0..100000]of longint; n,i,m,x,y,k,v,len:longint; procedure qsort(l,h:longint); var i,j,t,m:longint; b

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

http://poj.org/problem?id=2104 题意:给出n个数和m个询问求区间第K小. 思路:以前用主席树做过,这次学整体二分来做.整体二分在yr大佬的指点下,终于大概懂了点了.对于二分能够解决的询问,如果有多个,那么如果支持离线处理的话,那么就可以使用整体二分了. 在这题二分可行的答案,根据这个答案,把询问操作丢在左右两个队列里面分别递归继续按这样处理.注释里写的很详细. 1 #include <iostream> 2 #include <cstdlib> 3 #

【POJ 2104】K-th Number

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

【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

ACM-ICPC 2018 沈阳赛区网络预赛 K. Supreme Number

A prime number (or a prime) is a natural number greater than 11 that cannot be formed by multiplying two smaller natural numbers. Now lets define a number NN as the supreme number if and only if each number made up of an non-empty subsequence of all

K Best(最大化平均数)_二分搜索

Description Demy has n jewels. Each of her jewels has some value vi and weight wi. Since her husband John got broke after recent financial crises, Demy has decided to sell some jewels. She has decided that she would keep k best jewels for herself. Sh

Codeforces Round #350 (Div. 2) F. Restore a Number 模拟构造题

F. Restore a Number Vasya decided to pass a very large integer n to Kate. First, he wrote that number as a string, then he appended to the right integer k — the number of digits in n. Magically, all the numbers were shuffled in arbitrary order while

lintcode: ugly number

问题描述 Ugly number is a number that only have factors 3, 5 and 7. Design an algorithm to find the Kth ugly number. The first 5 ugly numbers are 3, 5, 7, 9, 15 - 问题分析 这个题,有多种方法求解,常见的是有辅助数据结构,比如priority_queue,或是常说的最大最小堆也可. 解法一:时间复杂度O(k log k),空间复杂度O(k) 使

Lintcode: Kth Prime Number

Design an algorithm to find the kth number such that the only prime factors are 3, 5, and 7. The eligible numbers are like 3, 5, 7, 9, 15 ... Example If k=4, return 9. Challenge O(n log n) or O(n) time 这是丑数问题(Ugly Number), 思路参看: http://www.cppblog.co

POJ3111 K Best —— 01分数规划 二分法

题目链接:http://poj.org/problem?id=3111 K Best Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 11380   Accepted: 2935 Case Time Limit: 2000MS   Special Judge Description Demy has n jewels. Each of her jewels has some value vi and weight wi.