[POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]
可持久化线段树模板题。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> using namespace std; int n,q,tot,a[110000]; int root[2100000],Left[2100000],Right[2100000]; int val[2100000]; void Insert(const int l,const int r,const int root_l,int& root_r,const int d) { val[root_r=++tot]=val[root_l]+1; if(l==r)return ; int mid=l+((r-l)>>1); if(d<=mid) { Right[root_r]=Right[root_l]; Insert(l,mid,Left[root_l],Left[root_r],d); } else { Left[root_r]=Left[root_l]; Insert(mid+1,r,Right[root_l],Right[root_r],d); } return ; } int Query(const int l,const int r,const int root_l,const int root_r,const int d) { if(l==r)return l; int mid=l+((r-l)>>1),temp; temp=val[Left[root_r]]-val[Left[root_l]]; if(temp>=d)return Query(l,mid,Left[root_l],Left[root_r],d); return Query(mid+1,r,Right[root_l],Right[root_r],d-temp); } int main() { freopen("in","r",stdin); int i; vector<int> vec; scanf("%d%d",&n,&q); for(i=1;i<=n;++i) { scanf("%d",&a[i]); vec.push_back(a[i]); } sort(vec.begin(),vec.end()); vec.erase(unique(vec.begin(),vec.end()),vec.end()); for(i=1;i<=n;++i) { a[i]=lower_bound(vec.begin(),vec.end(),a[i])-vec.begin()+1; Insert(1,vec.size(),root[i-1],root[i],a[i]); } for(i=1;i<=q;++i) { int l,r,k; scanf("%d%d%d",&l,&r,&k); printf("%d\n",vec[Query(1,vec.size(),root[l-1],root[r],k)-1]); } return 0; }