Description
Data Constraint
Solution
对于S和S’,我们可以用主席树很轻松的求出,但不能求出二关键字的k大。所以我们考虑整体二分。我们可以求出排名在[x,y]内的元素的范围[a,b]。对于一个范围[l,r]设满足排名k在该区间的询问[x,y],我们二分出mid,对于一个询问,若满足区间[l,r]内第一关键字在[a,b]且满足第二关键字小于mid的数量少于k,则答案一定在[l,mid]内。因为满足区间[l,r]内因为第二关键字是排列,我们将第二关键字在[l,mid]内的元素按位置排序,并将询问拆成[1,l-1],[1,r]两个询问,然后维护一个指针时期插入的数的位置小于询问,将第一关键字插入至树状数组查询即可。时间复杂度O(
Code
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=3e4+5,maxn1=2e5+5;
struct code{
int l,r,num;
}f[maxn*20];
struct code2{
int x,id;
}c[maxn];
struct code1{
int l,r,x,y,k,id;
}q[maxn1],q1[maxn1];
int a[maxn1],b[maxn1],d[maxn1],ans[maxn1],g[maxn1];
int n,m,i,t,j,k,l,x,y,z,num;
bool cmp(code2 x,code2 y){
return x.x<y.x;
}
bool cmp1(code2 x,code2 y){
return x.id<y.id;
}
bool cmp2(code1 x,code1 y){
return x.l<y.l;
}
void insert(int l,int r,int &v,int x){
int mid=(l+r)/2;
f[++num]=f[v];v=num;f[v].num++;
if (l==r) return;
if (mid>=x) insert(l,mid,f[v].l,x);
else insert(mid+1,r,f[v].r,x);
}
void find(int l,int r,int v,int v1,int x){
int mid=(l+r)/2;
if (l==r){
t=l;return;
}
if (x>f[f[v].l].num-f[f[v1].l].num) find(mid+1,r,f[v].r,f[v1].r,x-(f[f[v].l].num-f[f[v1].l].num));
else find(l,mid,f[v].l,f[v1].l,x);
}
void insert1(int x,int z){
while (x<=n) g[x]+=z,x+=(x&(-x));
}
int find1(int x){
int t=0;
while (x>0) t+=g[x],x-=(x&(-x));
return t;
}
void dg(int l,int r,int x,int y){
int mid=(l+r)/2;
if (x>y) return;
if (l==r){
for (i=x;i<=y;i++)
ans[q[i].id]=l;
return;
}
sort(c+l,c+mid+1,cmp1);
num=0;
for (i=x;i<=y;i++){
q1[++num]=q[i];q1[++num]=q[i];q1[num-1].l--;
q1[num].l=q[i].r;q1[num-1].r=-1;q1[num].r=1;
}
sort(q1+1,q1+num+1,cmp2);j=l;
for (i=1;i<=num;i++){
while (c[j].id<=q1[i].l && j<=mid) insert1(a[c[j++].id],1);
d[q1[i].id]+=(find1(q1[i].y)-find1(q1[i].x-1))*q1[i].r;
}j--;
while (j>=l)
insert1(a[c[j--].id],-1);
int num=0;
for (i=x;i<=y;i++)
if (ans[q[i].id]+d[q[i].id]>=q[i].k) q1[++num]=q[i];
int t=num;
for (i=x;i<=y;i++)
if (ans[q[i].id]+d[q[i].id]<q[i].k) q1[++num]=q[i],ans[q[i].id]+=d[q[i].id];
for (i=x;i<=y;i++)q[i]=q1[i-x+1],d[q[i].id]=0;
sort(c+l,c+mid+1,cmp);
dg(l,mid,x,x+t-1);dg(mid+1,r,x+t,y);
}
int main(){
freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]),d[i]=d[i-1],insert(1,n,d[i],a[i]);
for (i=1;i<=n;i++)scanf("%d",&b[i]),c[i].x=b[i],c[i].id=i;
sort(c+1,c+n+1,cmp);
scanf("%d",&m);
for (i=1;i<=m;i++){
scanf("%d%d%d%d%d",&q[i].l,&q[i].r,&x,&y,&q[i].k);q[i].id=i;
t=0;find(1,n,d[q[i].r],d[q[i].l-1],x);q[i].x=t;
t=0;find(1,n,d[q[i].r],d[q[i].l-1],y);q[i].y=t;
}
memset(d,0,sizeof(d));
dg(1,n,1,m);
for (i=1;i<=m;i++) printf("%d\n",ans[i]);
}