A - K-th Number POJ - 2104 -主席樹第一彈-第K大的數
阿新 • • 發佈:2018-11-28
- 感謝:http://www.cnblogs.com/zyf0163/p/4749042.html
- https://blog.csdn.net/qq_24451605/article/details/49031123
- 裸題多次查詢給定區間L—R內第K大的數
-
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define maxn 123456 struct node { int l,r,sum; } tree[maxn*30]; int n,cnt,k,snum,a[maxn]; int m,root[maxn],num[maxn]; void build(int &u,int l,int r) { u=++cnt; tree[u].sum=0; if(l==r)return; int mid=(l+r)/2; build(tree[u].l,l,mid); build(tree[u].r,mid+1,r); } void updata(int p,int &u,int l,int r,int x) { u=++cnt; tree[u]=tree[p]; tree[u].sum++; int mid=(l+r)/2; if(l==r)return; if(x>mid) updata(tree[p].r,tree[u].r,mid+1,r,x); else updata(tree[p].l,tree[u].l,l,mid,x); } int query(int t1,int t2,int l,int r,int k) { if(l==r)return l; int mid=(l+r)/2; int lf=tree[tree[t2].l].sum-tree[tree[t1].l].sum; if(lf>=k) return query(tree[t1].l,tree[t2].l,l,mid,k); else return query(tree[t1].r,tree[t2].r,mid+1,r,k-lf); } int main() { while(~scanf("%d%d",&n,&m)) { cnt=0; for(int i=1; i<=n; i++) { scanf("%d",&a[i]); num[i]=a[i]; } sort(num+1,num+n+1); snum=unique(num+1,num+1+n)-num-1; build(root[0],1,snum); for(int i=1; i<=n; i++) { int x=lower_bound(num+1,num+1+n,a[i])-num; updata(root[i-1],root[i],1,snum,x); } while(m--) { int l,r,k; scanf("%d%d%d",&l,&r,&k); int x=query(root[l-1],root[r],1,snum,k); printf("%d\n",num[x]); } } return 0; }