描述
你為macrohard公司的資料結構部門工作,你的工作是重新寫乙個資料結構,這個資料結構能快速地找到一段數列中第k大的數。
就是說,給定乙個整數數列a[1..n],其中每個元素都不相同,你的程式要能回答一組格式為q (i , j , k)的查詢,q(i, j ,k)的意思是「在a[i..j]中第k大的數是多少?」
例如令 a = ,查詢格式為q (2 , 5 , 3),數列段a[2..5] = ,第3大的數是5,所以答案是5。
輸入檔案第一行包括乙個正整數n,代表數列的總長度,還有乙個數m,代表有m個查詢。 n,m滿足:1≤n≤100 000, 1≤m≤5 000 第二行有n個數,代表數列的元素,所有數都不相同,而且不會超過109 接下來有m行,每行三個整數i , j , k,代表一次查詢, i , j , k滿足1≤i≤j≤n, 1≤k≤j − i + 1
輸出輸出每個查詢的答案,用換行符隔開
樣例輸入[複製]
7 31 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3
樣例輸出[複製]56
3
1/*template of chair tree
2lower_bound函式是用來返回乙個值在單調遞增數列裡大於等於這個值的最小值
3upper_bound函式實際上就是將lower_bound裡面的大於等於改成了嚴格大於
4這裡p的作用僅僅是在記錄這個點的編號,我們用一維陣列來儲存樹,只是該指向哪個位置
5同時我們輸入了幾個數就維護那麼大的區間,不一定一定要從1列舉到最大值,比如說1,8,5,4
6僅需要四個陣列位置,我每往後加乙個數字就要建一棵節約空間的線段樹,類似於ac自動機的思想
7那麼這個陣列對應的a陣列就是 1,4,3,2,每加乙個就相當於乙個節點修改了值然後向上維護,不過這
8裡沒有使用pushup函式,而是直接在二分的過程中進行累加,可以更好地維護值
9為什麼我們要維護這麼多棵線段樹,因為我們要像字首和陣列一樣通過乙個版本減去前面的版本
10來獲得所需區間的排序資訊,再進行二分就可以了.
1112
*/13 #include14
#define n 100005
15using
namespace
std;
16struct
nodet[n*40
];19
int a[n],b[n],n,m,rt[n*40
];20
int tot=0
;21 inline void build(int &p,int l,int r)
29 inline void update(int &p,int l,int r,int o,int
k)41 inline int query(int p1,int p2,int l,int r,int
k)48 inline long
long
read()
55while
(isdigit(ch))
59return ans*w;60}
61 inline void write(long
long
x)66
if(x>9)write(x/10
);67 putchar(x%10+'0'
);68}69
intmain()
76 sort(b+1,b+n+1);//
lower_bound函式必須是嚴格單調遞增,配合unique函式
77int siz=unique(b+1,b+n+1)-b-1;//
進行去重操作
78 build(rt[0],1,siz);//
對第0棵樹進行建圖
79for(int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+siz+1,a[i])-b;
80/*
找到a[i]該在的位置,此時a陣列的作
81用變為了記錄對應數字應該在的下標 ,
82類似於一般我們是陣列下標對應值,而
83這裡新加的操作就是原數列的每個值
84應該對應到排序過後的第幾個位置,
85相當於第幾名
86*/
87for(int i=1;i<=n;++i)update(rt[i],1,siz,rt[i-1
],a[i]);
88while(m--)
93return0;
94 }
區間第k大的數 主席樹
套主席樹求區間第k小的數的模板,然後求區間 l,r 第k大的數就等於求區間 l,r 第r l 1 k小的數 下標從1開始 區間第k小值問題 有n個數,多次詢問乙個區間 l,r 中第k小的值是多少。查詢區間 l,r 中的第k小值 我們按照從1到n的順序依次將資料插入可持久化的線段樹中,將會得到n 1個...
區間第k大(主席樹)
學了一下主席樹模板題,當初看了網上的主席樹講解都沒有看懂,後面看了嗶哩嗶哩的uestc的主席樹,終於看懂了思想。每次更新的複雜度都為logn。每次更新的話就是對要更新的點路徑上的點重新更加乙個,然後進行對沒有影響的那些進行連邊。然後用乙個root記錄每乙個線段樹的根節點下標。include incl...
主席樹區間第K大
主席樹的實質其實還是一顆線段樹,然後每一次修改都通過上一次的線段樹,來新增新邊,使得每次改變就改變logn個節點,很多節點重複利用,達到節省空間的目的。1.不帶修改的區間第k大。hdu 2665 模板題 1 include2 using namespace std 3 define fopen fr...