线段树
按能力值从小到大排序,
预处理以第i个人为组长的最大组
然后按能力值反向做更新线段树
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define pb push_back
#define ll o<<1
#define rr o<<1|1
#define mid (l+r)/2
const int N=1e5+100;
struct Node {
int r,a,id;
bool operator<(const Node & th)const{
return r<th.r;
}
}node[N];
int aa[N],top;
int cc[N];
int qu(int x){
int ans=0;
while(x){
ans+=cc[x];x-=x&-x;
}
return ans;
}
void up(int x){
while(x<=top){
cc[x]+=1;x+=x&-x;
}
}
int L,R;
int mx[N<<2];
void update(int l,int r,int o,int x,int v){
if(l==r){
mx[o]=max(mx[o],v);return ;
}
if(x<=mid)update(l,mid,ll,x,v);
else update(mid+1,r,rr,x,v);
mx[o]=max(mx[ll],mx[rr]);
}
int query(int l,int r,int o){
if(L<=l&&r<=R){
return mx[o];
}
int ans=-1;
if(L<=mid)ans=max(ans,query(l,mid,ll));
if(R>mid)ans=max(ans,query(mid+1,r,rr));
return ans;
}
int num[N];
int ag[N],ra[N];
int ask[N][2];
int ans[N];
int n,k;
int fun(int x){
//printf("%d %dask\n",ask[x][0],ask[x][1]);
int l=ag[ask[x][0]],r=ag[ask[x][1]];
if(l>r)swap(l,r);
int ans=-1;
L=lower_bound(aa,aa+top,r-k)-aa+1;R=lower_bound(aa,aa+top,l+k)-aa+1;
if(R>top||aa[R-1]>l+k)R--;
if(L<=R)ans=query(1,top,1);
return ans;
}
vector<int> vv[N];
int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
while(scanf("%d%d",&n,&k)!=EOF){
for(int i=0;i<n;i++)scanf("%d",&node[i].r),node[i].id=i,ra[i]=node[i].r;
for(int i=0;i<n;i++)scanf("%d",&node[i].a),aa[i]=node[i].a,ag[i]=aa[i];
sort(aa,aa+n);top=unique(aa,aa+n)-aa;
for(int i=0;i<n;i++){
node[i].a=lower_bound(aa,aa+top,node[i].a)-aa+1;
}
sort(node,node+n);
// for(int i=0;i<n;i++){
// printf("%d %d\n",node[i].a,node[i].r);
// }printf("node\n");
memset(cc,0,sizeof(cc));
for(int i=0;i<n;i++){
int j=i;up(node[j].a);
while(j+1<n&&node[j+1].r==node[i].r){
j++;up(node[j].a);
}
for(int k1=i;k1<=j;k1++){
int r=lower_bound(aa,aa+top,aa[node[i].a-1]+k)-aa+1;
if(r>top||aa[r-1]>aa[node[i].a-1]+k)r--;
int l=lower_bound(aa,aa+top,aa[node[i].a-1]-k)-aa+1;
num[k1]=qu(r)-qu(l-1);
}
i=j;
}
// for(int i=0;i<n;i++)printf("%d ",num[i]);printf("num\n");
for(int i=0;i<n;i++)vv[i].clear();
int q;scanf("%d",&q);
for(int i=0;i<q;i++){
int x,y;scanf("%d%d",&x,&y);x--;y--;
ask[i][0]=x;ask[i][1]=y;
if(ra[x]>=ra[y])vv[x].pb(i);
if(ra[y]>=ra[x])vv[y].pb(i);
}
memset(mx,-1,sizeof(mx));
memset(ans,-1,sizeof(ans));
for(int i=n-1;i>=0;i--){
int j=i;update(1,top,1,node[j].a,num[j]);
while(j-1>=0&&node[j-1].r==node[i].r){
j--;update(1,top,1,node[j].a,num[j]);
}
for(int k2=j;k2<=i;k2++){
int id=node[k2].id;
for(int k1=0;k1<vv[id].size();k1++){
ans[vv[id][k1]]=max(ans[vv[id][k1]],fun(vv[id][k1]));
}
}
i=j;
}
for(int i=0;i<q;i++){
printf("%d\n",ans[i]);
}
}
return 0;
}