1157 - 造物主的戒律
Time Limit:20s Memory Limit:512MByte
Submissions:661Solved:68
DESCRIPTION
造物主的戒律,空气,变成数据结构!
于是空气变成了数据结构~
给你一个序列,每次查询区间中小于等于x的所有数字里面第k1k1小的值以及大于x的所有数字里面第k2k2小的值,如果不存在,输出-1
每次输出两个数,对于每个数如果不存在,则单独输出-1
INPUT
第一行两个数n,m第二行n个数表示序列a后面m行每行五个数l,r,x,k1,k2
OUTPUT
对于每个查询输出答案
SAMPLE INPUT
5 5
1 2 3 4 5
1 5 3 1 2
2 5 2 1 3
2 3 3 3 3
3 3 3 3 3
3 3 3 3 3
1 2 3 4 5
1 5 3 1 2
2 5 2 1 3
2 3 3 3 3
3 3 3 3 3
3 3 3 3 3
SAMPLE OUTPUT
1 5
2 5
-1 -1
-1 -1
-1 -1
2 5
-1 -1
-1 -1
-1 -1
HINT
n,m<= 400000 ,0 <= a[i] <= 1000000000
解:首先查询在这个区间中比x小的数的个数,如果小于k1 ans1=-1,否则查询第k1小的数,如果cnt+k2>r-l+1则ans2=-1 否则查询cnt+k2大的数;
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include <bits/stdc++.h>
using namespace std;
const int N = 4e5+100;
typedef long long LL;
int rt[N], ls[N*100], rs[N*100], sum[N*100];
int a[N], b[N], tot, tmp;
void build(int &o,int l,int r)
{
o= ++tot,sum[o]=0;
if(l==r) return ;
int mid=(l+r)/2;
build(ls[o],l,mid);
build(rs[o],mid+1,r);
return ;
}
void update(int &o,int l,int r,int last,int p)
{
o= ++tot;
ls[o]=ls[last],rs[o]=rs[last];
sum[o]=sum[last]+1;
if(l==r) return ;
int mid=(l+r)/2;
if(p<=mid) update(ls[o],l,mid,ls[last],p);
else update(rs[o],mid+1,r,rs[last],p);
return ;
}
void query(int ss,int tt,int l,int r,int p)
{
if(l==r)
{
tmp+=(sum[tt]-sum[ss]);
return ;
}
int mid=(l+r)/2;
if(p<=mid)
{
query(ls[ss],ls[tt],l,mid,p);
}
else
{
tmp+=(sum[ls[tt]]-sum[ls[ss]]);
query(rs[ss],rs[tt],mid+1,r,p);
}
return ;
}
int query1(int ss,int tt,int l,int r,int cnt)
{
if(l==r) return l;
int tmp1=sum[ls[tt]]-sum[ls[ss]];
int mid=(l+r)/2;
if(tmp1>=cnt) return query1(ls[ss],ls[tt],l,mid,cnt);
else return query1(rs[ss],rs[tt],mid+1,r,cnt-tmp1);
}
int main()
{
int n, q;
scanf("%d %d", &n, &q);
for(int i=1; i<=n; i++) scanf("%d", &a[i]), b[i]=a[i];
sort(b+1,b+n+1);
int k=unique(b+1,b+n+1)-(b+1);
tot=0;
build(rt[0],1,k);
for(int i=1; i<=n; i++)
{
int pos=lower_bound(b+1,b+k+1,a[i])-(b);
update(rt[i],1,k,rt[i-1],pos);
}
while(q--)
{
int l, r, x, k1, k2;
scanf("%d %d %d %d %d", &l, &r, &x, &k1, &k2);
tmp=0;
int pos=lower_bound(b+1,b+k+1,x)-b;
if(b[pos]!=x) pos--;
query(rt[l-1],rt[r],1,k,pos);
int ans1=0, ans2=0;
if(tmp<k1) ans1=-1;
else ans1=b[query1(rt[l-1],rt[r],1,k,k1)];
if(tmp+k2>r-l+1) ans2=-1;
else ans2=b[query1(rt[l-1],rt[r],1,k,tmp+k2)];
printf("%d %d\n",ans1,ans2);
}
return 0;
}