查询区间第 K 小的数,这个二分+树状数组足够了啊。
虽然我是想练练treap 的,但是看到能写 BIT 就停不下来啊。。。
离散化好恶心。。。用map T 到死。还有大于1000W 的数数组开不下,只能 hash。
找了两三个素数才过的去。
hash的时候素数不是越大越好啊。。?
中途开了好多个struct来保存信息。。。
#include <stdio.h>
#include <iostream>
#include <queue>
#include <algorithm>
#include <map>
#include <vector>
#include <cmath>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <fstream>
using namespace std;
#define READ freopen("acm.in","r",stdin)
#define ll long long
#define PII pair<int,int>
#define PDI pair<double,int>
#define PDD pair<double,double>
#define MPI map<int,int>::iterator
#define fst first
#define sec second
#define MS(x,d) memset(x,d,sizeof(x))
#define INF 0x3f3f3f3f
#define ALL(x) x.begin(),x.end()
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MAX 200000
#define ROOT 0,n-1,1
#define PB push_back
#define FOR(a,b,c) for(int a=b;a<c;a++)
#define MOD 486377
struct answer
{
int i,ans;
bool operator < (const answer &o) const
{
return i<o.i;
}
}Ans[MAX];
struct q
{
int l,r,k,i;
bool operator < (const q &o) const
{
if(r==o.r)
return l<o.l;
return r<o.r;
}
}Q[MAX];
struct hashNode
{
int num;
int i;
};
int data[2000000];
int n,m;
int num[MAX];
void add(int i,int x)
{
while(i<=n)
{
data[i]+=x;
i+=i&(-i);
}
}
int sum(int i)
{
int res=0;
while(i>0)
{
res+=data[i];
i-=i&(-i);
}
return res;
}
int query(int k)
{
int lb=0,ub=n;
while(ub-lb>1)
{
int mid=(lb+ub)>>1;
if(sum(mid)>=k)
ub=mid;
else
lb=mid;
}
return ub;
}
vector<int> uni;
vector<hashNode> mp[1000000];
void hash(int n,int i)
{
mp[n%MOD].PB((hashNode){n,i});
}
int getHash(int n)
{
for(int i=0;i<mp[n%MOD].size();i++)
if(n==mp[n%MOD][i].num)
return mp[n%MOD][i].i;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<1000000;i++)
mp[i].clear();
uni.clear();
MS(data,0);
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
uni.PB(num[i]);
}
sort(ALL(uni));
uni.erase(unique(ALL(uni)),uni.end());
for(int i=0;i<uni.size();i++)
hash(uni[i],i+1);
for(int i=1;i<=m;i++)
{
int l,r,k,in;
scanf("%d%d%d",&l,&r,&k);
Q[i]=(q){l,r,k,i};
}
sort(Q+1,Q+1+m);
int L=1,R=1,nq=1;
while(nq<=m)
{
while(R<=Q[nq].r)
{
add(getHash(num[R]),1);
R++;
}
while(L<Q[nq].l)
{
add(getHash(num[L]),-1);
L++;
}
Ans[nq]=(answer){Q[nq].i,uni[query(Q[nq].k)-1]};
nq++;
}
sort(Ans+1,Ans+1+m);
for(int i=1;i<=m;i++)
printf("%d\n",Ans[i].ans);
}
return 0;
}