POJ2104 K-th Number【劃分樹】
K-th Number
Time Limit: 20000MS | Memory Limit: 65536K | |
Total Submissions: 68626 | Accepted: 24285 | |
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
題解:求區間[l,r]的第K小數,劃分樹模板題
AC的C++程式碼:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100100;
const int Deep=20;
struct PartitionTree{
int num[N],cnt[N];
}tree[Deep];
int sorted[N];
void build(int deep,int l,int r)
{
if(l==r)
return;
int mid=(l+r)>>1;
int key=sorted[mid];
int scnt=mid-l+1;
for(int i=l;i<=r;i++)
if(tree[deep].num[i]<key)
scnt--;
int p=l-1,p2=mid;
for(int i=l,cnt=0;i<=r;i++){
int num=tree[deep].num[i];
if(num<key||(num==key&&scnt)){
if(num==key)
scnt--;
cnt++;
tree[deep+1].num[++p]=num;
}
else
tree[deep+1].num[++p2]=num;
tree[deep].cnt[i]=cnt;
}
build(deep+1,l,mid);
build(deep+1,mid+1,r);
}
int query(int deep,int l,int r,int L,int R,int k)
{
if(l==r)
return tree[deep].num[l];
int mid=(l+r)>>1;
int left=0,sum_in_left=tree[deep].cnt[R];
if(l!=L){
left=tree[deep].cnt[L-1];
sum_in_left-=left;
}
if(sum_in_left>=k){
L=l+left;
R=L+sum_in_left-1;
return query(deep+1,l,mid,L,R,k);
}
else{
int a=L-l-left;
int b=R-L+1-sum_in_left;
L=mid+1+a;
R=L+b-1;
return query(deep+1,mid+1,r,L,R,k-sum_in_left);
}
}
int main()
{
int n,m,L,R,k;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&sorted[i]);
tree[0].num[i]=sorted[i];
}
sort(sorted+1,sorted+1+n);
build(0,1,n);
while(m--){
scanf("%d%d%d",&L,&R,&k);
printf("%d\n",query(0,1,n,L,R,k));
}
return 0;
}
相關文章
- 劃分樹
- [資料結構] 劃分樹資料結構
- 劃分樹模板+模板題--hdu4251
- hdu--4417Super Mario+劃分樹
- HDU2665 Kth number【主席樹】
- D - K-th NearestREST
- [LeetCode] K-th Smallest Prime Fraction 第K小的質分數LeetCodeFraction質分數
- HDU 1394 Minimum Inversion Number (暴力+線段樹)
- [NOIP2015 提高組] 運輸計劃(二分 + lca + 樹上差分)
- hud--4251The Famous ICPC Team Again+劃分樹入門題AI
- 刷題系列 - K-th 語法
- 點分樹
- WAF的幾種劃分方法和劃分型別型別
- 樹鏈剖分
- Note - 樹分治(點分治、點分樹)
- 資料劃分
- 單詞劃分
- 服務劃分
- 子網劃分
- zone的劃分
- abc372E K-th Largest Connected Components
- K-th 問題的一般思路
- 動態規劃之數的劃分動態規劃
- 2024.3.14 樹鏈剖分
- [OI] 樹鏈剖分
- 【PAT甲級A1038】Recover the Smallest Number (30分)(c++)C++
- 如何劃分微服務微服務
- 01 分數規劃
- 集合劃分 題解
- 01分數規劃
- 陣列元素劃分陣列
- 詳解平衡二叉樹的失衡型別劃分及調整策略設計二叉樹型別
- 等長子網劃分、變長子網劃分(網路整理)
- 樹鏈剖分總結
- 分類——決策樹模型模型
- 淺談樹鏈剖分
- Something about 樹鏈剖分
- Linux 上如何劃分VLANLinux