【题解】
跟51nod 1105差不多。
二分答案求出第L个数和第R个数,check的时候再套一个二分或者用two pointers.
最后枚举ai在b里面二分,找到所有范围内的数,排序后输出。
注意最后找到的数可能多于R-L+1,需要考虑这一点。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #define LL long long 6 #define rg register 7 #define N 100010 8 using namespace std; 9 LL tot,n,l,r,st,ed,mn,mx,a[N],b[N],ans[N]; 10 inline LL read(){ 11 LL k=0,f=1; char c=getchar(); 12 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 13 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 14 return k*f; 15 } 16 inline LL check(LL x){ 17 LL sum=0; 18 for(rg int i=1;i<=n;i++){ 19 LL tmp=x-a[i]+1; 20 sum+=lower_bound(b+1,b+1+n,tmp)-b-1; 21 // printf("sum=%d ",sum); 22 } 23 // printf("sum=%d ",sum); 24 return sum; 25 } 26 int main(){ 27 n=read(); st=read(); ed=read(); 28 for(rg int i=1;i<=n;i++) a[i]=read(); sort(a+1,a+1+n); 29 for(rg int i=1;i<=n;i++) b[i]=read(); sort(b+1,b+1+n); 30 l=a[1]+b[1]-1; r=a[n]+b[n]; 31 while(l+1<r){ 32 LL mid=(l+r)>>1; 33 if(check(mid)>=st) r=mid; else l=mid; 34 } 35 mn=r; 36 l=a[1]+b[1]-1; r=a[n]+b[n]; 37 while(l+1<r){ 38 LL mid=(l+r)>>1; 39 if(check(mid)>=ed) r=mid; else l=mid; 40 } 41 mx=r; 42 // printf("%d %d ",mn,mx); 43 for(rg int i=1;i<=n;i++){ 44 int tmp=mn-a[i],tmp2=mx-a[i]; 45 int pos1=lower_bound(b+1,b+1+n,tmp)-b; 46 if(pos1==n+1) continue; 47 int pos2=upper_bound(b+1,b+1+n,tmp2)-b; 48 // printf("%d %d ",pos1,pos2); 49 for(rg int j=pos1;j<pos2;j++) ans[++tot]=a[i]+b[j]; 50 } 51 sort(ans+1,ans+1+tot); 52 tot=min(tot,ed-st+1); 53 for(rg int i=1;i<=tot;i++) printf("%lld ",ans[i]); 54 return 0; 55 }