Solution
发现,那个条件2其实没有用,可以用主席树预处理一下,转为数值在x,y之间,
那么这题就变成了求二维平面上的第k大,
这个用整体二分即可,
复杂度: O(nlog(n)2)
Code
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define min(q,w) ((q)>(w)?(w):(q))
#define max(q,w) ((q)<(w)?(w):(q))
#define NX(q) ((q)&(-(q)))
#define Gsum(l,r) (find(r)-find((l)-1))
using namespace std;
const int N=100500;
int read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int m,n,ans;
struct qqww
{
int x,y,v;
}a[N],p1[N];
struct qwqw
{
int x,y,v,i,k,p;
}b[N*2],pb[N*2];
int root[N],b10;
struct qwqwq
{
int l,r,v;
}b1[N*70];
int f[N];
int c[N],Ans[N];
bool PX(qwqw q,qwqw w){return q.p<w.p;}
void build(int l,int r,int e1,int &e,int l1)
{
if(!e||e1==e)b1[e=++b10]=b1[e1];
if(l==r){b1[e].v++;return;}
b1[e].v++;
int t=(l+r)>>1;
if(l1<=t)build(l,t,b1[e1].l,b1[e].l,l1);
else build(t+1,r,b1[e1].r,b1[e].r,l1);
}
int findr(int l,int r,int e1,int e,int l1)
{
if(l==r)return l;
int t=(l+r)>>1;
if(!b1[e].r||b1[b1[e].l].v-b1[b1[e1].l].v>=l1)return findr(l,t,b1[e1].l,b1[e].l,l1);
return findr(t+1,r,b1[e1].r,b1[e].r,l1-b1[b1[e].l].v+b1[b1[e1].l].v);
}
void add(int q,int e){for(int i=q;i<=n;i+=NX(i))f[i]+=e;}
int find(int q)
{
int ans=0;
for(int i=q;i;i-=NX(i))ans+=f[i];
return ans;
}
void divide(int l,int r,int L,int R,int L1,int R1)
{
if(l==r)
{
fo(i,L1,R1)Ans[b[i].i]=l;
return;
}
if(L1>R1||L>R)return;
int t=(l+r)>>1;
int T=0;
fo(i,L,R)
{
a[i-T]=a[i];
if(a[i].v>t)p1[++T]=a[i];
}
T=R-T;
fo(i,T+1,R)a[i]=p1[i-T];
int q=L1;
fo(i,L,T)
{
for(;b[q].p<a[i].x&&q<=R1;q++)
{
c[b[q].i]+=b[q].k*Gsum(b[q].x,b[q].y);
}
add(a[i].y,1);
}
for(;q<=R1;q++)c[b[q].i]+=b[q].k*Gsum(b[q].x,b[q].y);
q=0;
fo(i,L1,R1)
{
b[i-q]=b[i];
if(c[b[i].i]<b[i].v)
{
b[i].v-=c[b[i].i];
q++;
pb[q]=b[i];
}
if(b[i].k>0)c[b[i].i]=0;
}
fo(i,R1-q+1,R1)b[i]=pb[i-R1+q];
fo(i,L,T)add(a[i].y,-1);
divide(l,t,L,T,L1,R1-q);
divide(t+1,r,T+1,R,R1-q+1,R1);
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
int q,w,e,_,l,r,x,y;
read(n);
fo(i,1,n)read(a[i].y),a[i].x=i;
fo(i,1,n)
{
read(a[i].v);
build(1,n,root[i-1],root[i],a[i].y);
}
read(m);
fo(i,1,m)
{
read(b[i*2-1].p),read(b[i*2].p);
b[i*2-1].p--;
read(q),read(w);
b[i*2].x=b[i*2-1].x=findr(1,n,root[b[i*2-1].p],root[b[i*2].p],q);
b[i*2].y=b[i*2-1].y=findr(1,n,root[b[i*2-1].p],root[b[i*2].p],w);
b[i*2].v=read(b[i*2-1].v);
b[i*2-1].k=-1;b[i*2].k=1;
b[i*2-1].i=b[2*i].i=i;
}
sort(b+1,b+1+2*m,PX);
divide(1,n,1,n,1,m*2);
fo(i,1,m)printf("%d\n",Ans[i]);
return 0;
}