標籤:演算法 資料結構
用這個模板可以直接A掉 HDU 2665 Kth number 這題了!
/* 主席樹求區間第K大模板: * 模板特殊說明: * 每棵樹是維護從1開始到cnt的下標資訊 */#include <stdio.h>#include <algorithm>#define maxn 100010using namespace std;int T, n, m, tot, a[maxn], b[maxn], cnt; //T為輸入cas組數,n為原數列數組個數,m為詢問個數,tot為建樹時新節點 //a為原數列,b為用來離散化的數列,其unique後元素個數為cntstruct N { int ls, rs, w; } tree[30 * maxn]; //ls為左兒子節點下標,rs為右兒子節點下標,w為此區間內元素數量int roots[maxn]; //roots記錄每棵樹的根節點下標int build_tree(int l, int r) { //先建造一棵空樹 int newnode = tot++; tree[newnode].w = 0; if (l != r) { int mid = (l + r) / 2; tree[newnode].ls = build_tree(l, mid); tree[newnode].rs = build_tree(mid + 1, r); } return newnode;}int updata(int rt, int pos, int val) { //rt為根節點,在pos位置上加val的值 int newnode = tot++, tmp = newnode; tree[newnode].w = tree[rt].w + val; int l = 1, r = cnt; while (l < r) { int mid = (l + r) / 2; if (pos <= mid) { tree[newnode].ls = tot++; tree[newnode].rs = tree[rt].rs; newnode = tree[newnode].ls; rt = tree[rt].ls; r = mid; } else { tree[newnode].ls = tree[rt].ls; tree[newnode].rs = tot++; newnode = tree[newnode].rs; rt = tree[rt].rs; l = mid + 1; } tree[newnode].w = tree[rt].w + val; } return tmp;}int query(int rt1, int rt2, int k) { //詢問根節點分別為rt1,rt2兩棵樹之間第k大的值 int l = 1, r = cnt; while (l < r) { int mid = (l + r) / 2; int tmp = tree[tree[rt2].ls].w - tree[tree[rt1].ls].w; if (tmp >= k) { rt1 = tree[rt1].ls; rt2 = tree[rt2].ls; r = mid; } else { k -= tmp; rt1 = tree[rt1].rs; rt2 = tree[rt2].rs; l = mid + 1; } } return l;}int main() { //freopen("in.in", "r", stdin); //freopen("out.out", "w", stdout); scanf("%d", &T); while (T--) { //讀入資料群組數 scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i - 1] = a[i]; } sort(b, b + n); cnt = unique(b, b + n) - b; //離散化 tot = 0; roots[0] = build_tree(1, cnt); for (int i = 1; i <= n; i++) { int tmp = (int)(lower_bound(b, b + cnt, a[i]) - b) + 1; roots[i] = updata(roots[i - 1], tmp, 1); //在上一次的基礎上建樹 } int l,r,k; for(int i=0;i<m;i++){ scanf("%d %d %d",&l,&r,&k); //讀入求l和r區間第k大的數 int tmp = query(roots[l-1],roots[r],k); printf("%d\n",b[tmp - 1]); } } return 0;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
主席樹模板