题目:给你一个n个数的序列,m个询问,每次询问为i,j,k,问区间[i,j]中的数按升序排序后,第k个数是什么
思路:CDQ分治,整体二分答案
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<ctime>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<list>
#include<numeric>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define INF 0x3f3f3f3f
#define mm(a,b) memset(a,b,sizeof(a))
#define PP puts("*********************");
template<class T> T f_abs(T a){ return a > 0 ? a : -a; }
template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
// 0x3f3f3f3f3f3f3f3f
//0x3f3f3f3f
const int maxn=110050;
struct Query{
int x,y,k,pos,type;
Query(int _x,int _y,int _k,int _pos,int _type):x(_x),y(_y),k(_k),pos(_pos),type(_type){}
Query(){}
}q[maxn],q1[maxn],q2[maxn];
struct BIT{
int n,b[maxn];
void init(int _n){
n=_n;
mm(b,0);
}
void add(int i,int val){
for(;i<=n;i+=i&(-i))
b[i]+=val;
}
int sum(int i){
int ret=0;
for(;i>0;i-=i&(-i))
ret+=b[i];
return ret;
}
}bit;
int arr[maxn],ans[maxn];
void solve(int L,int R,int l,int r){
if(L>R) return;
if(l==r){
for(int i=L;i<=R;i++)
if(q[i].type==2)
ans[q[i].pos]=l;
return;
}
int mid=(l+r)>>1;
int sz1=0,sz2=0;
for(int i=L;i<=R;i++){
if(q[i].type==1){
if(q[i].x<=mid){
bit.add(q[i].pos,1);
q1[sz1++]=q[i];
}
else
q2[sz2++]=q[i];
}
else{
int res=bit.sum(q[i].y)-bit.sum(q[i].x-1);
if(res>=q[i].k) q1[sz1++]=q[i];
else{
q[i].k-=res;
q2[sz2++]=q[i];
}
}
}
for(int i=0;i<sz1;i++)//清空
if(q1[i].type==1)
bit.add(q1[i].pos,-1);
memcpy(q+L,q1,sz1*sizeof(Query));
memcpy(q+L+sz1,q2,sz2*sizeof(Query));
solve(L,L+sz1-1,l,mid);
solve(L+sz1,R,mid+1,r);
}
int main(){
// freopen("D:\\input.txt","r",stdin);
// freopen("D:\\output.txt","w",stdout);
int n,m,x,y,k;
while(~scanf("%d%d",&n,&m)){
bit.init(n);
int idx=0;
for(int i=1;i<=n;i++){
scanf("%d",&arr[i]);
q[++idx]=Query(arr[i],1,1,i,1);
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&k);
q[++idx]=Query(x,y,k,i,2);
}
solve(1,idx,-INF,INF);
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
}
return 0;
}