主席树板子
找区间第k小的数+离散化
// Problem: K-th Number
// Contest: POJ - Northeastern Europe 2004
// URL: http://poj.org/problem?id=2104
// Memory Limit: 65 MB
// Time Limit: 20000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+9;
struct node{
int l,r;
ll c;
}seg[N<<5];
#define tl(id) seg[id].l
#define tr(id) seg[id].r
int a[N];
vector<int> X;
int root[N],index;
int binary(int x){
return lower_bound(X.begin(),X.end(),x)-X.begin()+1;
}
void pushup(int id){
seg[id].c=seg[tl(id)].c+seg[tr(id)].c;
}
void insert(int post,int &curr,int l,int r,int v){
curr=++index;
seg[curr]=seg[post];
if(l==r){
seg[curr].c++;
return;
}
int mid=(l+r)>>1;
if(mid>=v){
insert(tl(post),tl(curr),l,mid,v);
}else{
insert(tr(post),tr(curr),mid+1,r,v);
}
pushup(curr);
}
ll query(int post,int curr,int l,int r,int k){
ll c=seg[tl(curr)].c-seg[tl(post)].c;
if(l==r){
return l;
}
int mid=(l+r)>>1;
if(c>=k){
return query(tl(post),tl(curr),l,mid,k);
}else{
return query(tr(post),tr(curr),mid+1,r,k-c);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
X.push_back(a[i]);
}
sort(X.begin(),X.end());
X.erase(unique(X.begin(),X.end()),X.end());
int XN=X.size();
for(int i=1;i<=n;i++){
insert(root[i-1],root[i],1,XN,binary(a[i]));
}
for(int i=1;i<=m;i++){
int l,r,k;
cin>>l>>r>>k;
cout<<X[query(root[l-1],root[r],1,XN,k)-1]<<'\n';
}
return 0;
}
使用主席树解决区间第k小值问题:POJ2104K-thNumber
451

被折叠的 条评论
为什么被折叠?



