1. 程式人生 > >2104 】K-th Number 【分塊 (平方分割)+二分】

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 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 10 9 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<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define LL long long
#define ULL unsigned long long

const int N =  2e5+11;
const int M = 1e6+11;
const int inf =0x3f3f3f3f;
const int mod = 1e9+7;
const
int B = 1000; int a[N],b[N]; vector<int>ve[1000]; inline bool f(int x,int l,int r,int k){ int cnt=0; r++; while(l<r&&(l%B)!=0) if(a[l++]<=x) cnt++; while(l<r&&(r%B)!=0) if(a[--r]<=x) cnt++; while(l<r){ int zz=l/B; cnt+=upper_bound(ve[zz].begin(),ve[zz].end(),x)-ve[zz].begin(); l+=B; } if
(cnt>=k) return true; else return false; } int main(){ int n,m; scanf("%d %d",&n,&m); for(int i=0;i<n;i++){ scanf("%d",&a[i]); b[i]=a[i]; ve[i/B].push_back(a[i]); } sort(b,b+n); for(int i=0;i<n/B;i++) sort(ve[i].begin(),ve[i].end()); while(m--){ int x,y,z; scanf("%d %d %d",&x,&y,&z); int le,ri; le=0; ri=n-1; int ans; while(le<=ri){ int mid=(le+ri)>>1; if(f(b[mid],x-1,y-1,z)) { ans=mid; ri= mid-1; }else le=mid+1; } printf("%d\n",b[ans]); } return 0; }

相關推薦

2104 K-th Number 平方分割+二分

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were

2104K-th Number 歸併樹

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were

poj 2104K-th Number整體二分+樹狀陣列

傳送門 Description You are working for Macrohard company in data structures department. After failing your previous task about key

POJ 2104主席樹模板題K-th Number

題意:       靜態詢問區間第K大問題。給出一個數組,然後多次詢問某一區間第K大數是多少。   思路:       典型的主席樹模板題。       所以就大致講一下靜態主席樹

poj 2104K-th Number整體二分+樹狀陣列

傳送門biu~ 題目大意:給一串數字,多次詢問區間的第k小值。 思路:首先考慮一次詢問的情況,我們可以二分答案,然後通過驗證比答案大的數有多少個來不斷地縮小答案範圍直至得到一個準確的答案。而對於多個

POJ2104K-th Number

【POJ2104】K-th Number 題面 virtual judge 題解 其實就是一道主席樹\(sb\)題 但是為了學習整體二分的需要就用整體二分寫了。。。 所以主要利用此題講一下整體二分到底是個啥(以下部分參考李煜東《演算法競賽進階指南》): 兩個例子 \(Eg1\) 給定一個正整數序

poj2104K-th Number 歸併樹

說起來這是第二次A這個題了23333 第一次是分塊,戳這裡 歸併樹比分塊打起來爽,速度還快,簡直好評 思想:線段樹套陣列【霧。線段樹每個節點儲存它所表示的區間的有序數字排列。實現就是在歸併排序的過程中儲存歸併排序的過程。蠻好打的。 並且除錯什麼的也沒出什

劃分樹K-th Number

/* 此題採用劃分歸併樹進行計算 * 題號:poj 2104 */ #include #include #include #include #include #define MAXN 100010 using namespace std; int num[MAXN]; // 用於儲存輸入的陣列

POJ2104 K-th Number 歸併樹

K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 38379 Accepted: 12480 Case Time Limit: 2000MS   Descriptio

K-th NumberPOJ2104——主席樹

Time Limit: 20000MS Memory Limit: 65536K Case Time Limit: 2000MS Description You are working for Macrohard company in data s

POJ_2104 K-th Number 主席樹

uil 持久化 就是 lan pan lower 構造 宋體 之前 一 題面   K-th Number 二 分析   第一個主席樹的題,感觸蠻多吧,幾個關鍵點就是可持久化數據結構,這裏的主席樹其實就是保留了之前各個版本的權值線段樹,然後利用權值線段樹和歷史版本可以進

洛谷P2801教主的魔法二分

題目大意: 題目連結:https://www.luogu.org/problemnew/show/P2801 給出一串數列,有兩個操作: M

洛谷p2801教主的魔法模板

給出一個數列,支援區間修改,區間查詢大於等於key的值個數,分塊模板加一個小二分。 詳情見程式碼。A指查詢(L到R大於x),M指修改(將L到R增加x) #include<bits/stdc++.h> #define in in() using namespace std; i

洛谷P3203彈飛綿羊

題目大意: 題目連結:https://www.luogu.org/problemnew/show/P3203 有 n n

5037 線段樹練習4加強版 卡常

/** 5037 線段樹練習4加強版 連結:http://codevs.cn/problem/5037/ op 1 區間修改 op 2 區間多少個數為k的倍數; 依據資料範圍:可記錄每個塊內每個數字出現的次數 區間加操作,完整塊依舊0(1),非完整塊 直接暴力即

POJ 2104 K-th Number——平方分割

區間推薦左閉右開#include <cstdio> #include <cstring> #include <iostream> #include <algor

POJ 2104 K-th Number [主席樹入門]資料結構

題目連結:http://poj.org/problem?id=2104 ———————————————————————————————————————————————— K-th Number Time Limit: 20000MS Memory

POJ 2104 K-th Number(區間第k大數)平方切割,歸並樹,劃分樹

ac代碼 deb rank turn tracking line 查看 div 能夠 題目鏈接: http://poj.org/problem?id=2104 解題思路: 由於查詢的個數m非常大。樸素的求法無法在規定時間內求解。因此應該選用合理的方式維護數據來做到高效

POJ 2104 K-th Number主席樹

ber sca first n) 次數 example == scan sorted K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 5742

POJ 2104 K-th Number (主席樹)

std +++ esp space ctype == string uniq upd 題意:給定一個序列,然後有 q 個詢問,每次詢問 l - r 區間內的第 k 大的值。 析:很明顯的主席樹,而且還是裸的主席樹,先進行離散化,然後用主席樹進行查詢就好。 代碼如下: #p