题意:
给定长度为n的整数数组a,和长度为m的整数数组b,
表示在一维数轴上有n个红点a[i],和m个蓝点b[i],
给定一个实数c,对于每一个i,如果对于所有的j,
都满足|c-a[i]|<|c-b[j]|,那么红队分数+1,
现在你可以自定义c的值,计算红队可能获得的最大分数.
数据范围:n,m<=5e5
解法:
发现问题可以变为:
将a数组和b数组混合,问题变为计算最大子区间的长度,
满足整个区间只有红色,(因为可以取c为区间中点),
混合起来,排个序,然后尺取一下即可.
坑点:
观察到红点和蓝点可能重叠,这样的红点可以直接丢弃,
但是蓝点不能丢弃!
code:
#include <bits/stdc++.h>
using namespace std;
const int maxm=1e6+5;
struct Node{
int x,f;
}e[maxm];
int a[maxm];
int b[maxm];
int n,m;
bool cmp(Node a,Node b){
return a.x<b.x;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;cin>>T;
while(T--){
cin>>n>>m;
map<int,int>mark;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
cin>>b[i];
mark[b[i]]=1;
}
int num=0;
for(int i=1;i<=n;i++){
if(!mark[a[i]]){
e[++num]={a[i],0};
}
}
for(int i=1;i<=m;i++){
e[++num]={b[i],1};
}
sort(e+1,e+1+num,cmp);
int ans=0;
int cnt[2]={0};
int l=1;
for(int i=1;i<=num;i++){
cnt[e[i].f]++;
while(cnt[1]){
cnt[e[l].f]--;
l++;
}
ans=max(ans,i-l+1);
}
if(ans==0)cout<<"Impossible"<<endl;
else cout<<ans<<endl;
}
return 0;
}