Official

D - Impartial Gift Editorial by en_translator


Let \(S\) and \(T\) be multisets of gifts for Aoki and Snuke, respectively. (Having multiple gifts with the same value for the same person is obviously meaningless, but for implementation purpose, we assume that they are multisets).

Then, the problem can be solved by the following steps.

  1. Let \(s_0\) and \(t_0\) be the maximum element of \(S\) and \(T\), respectively. (Here, if it is impossible to choose the maximum element, that is, if \(S\) or \(T\) is an empty set, then clearly Takahashi cannot choose gifts to satisfy the conditions. In that case, print \(-1\) and stop the loop.

  2. If \(\lvert s_0-t_0\rvert \leq D\), then the answer to this problem is \(s_0+t_0\) regardless of the other elements of \(S\) and \(T\). Thus, print \((s_0+t_0)\) and terminate the loop.

  3. Otherwise, we divide into case depending on the ordering of \(s_0\) and \(t_0\). (Note that \(s_0\neq t_0\) by 2.)
    If \(s_0<t_0\), for any element \(s\), we have \(s<t_0\) and \(\lvert s-t_0\rvert=t_0-s\geq t_0-s_0>D\), so he cannot give a gift of value \(t_0\) to Snuke while satisfying the conditions. Thus, the answer to the problem remains the same even after removing the element \(t_0\) from \(T\). Thus, remove \(T\) from \(t_0\) and go back to 1.
    If \(s_0>t_0\), we can similarly remove \(s_0\) from \(S\) and go back to 1.

For every iteration of steps 1.-3., the sum of numbers of elements in \(S\) and \(T\) reduces by one, so this procedure stops after at most \((N+M)\) iterations.

Moreover, if we sort \(A\) and \(B\) beforehand, the reference to the maximum element in 1. corresponds to finding the last element, and removal of an element from either set in step 3. corresponds to the removal of the last element, so they can be done in an \(O(1)\) time using a vector.

Therefore, taking into account the complexity \(O(N\log N+M\log M)\) required for sorting, the total complexity is \(O(N\log N+M\log M)\), and the problem has been solved fast enough.

Sample code in C++:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < n; ++i)


int main(void){
	int n,m;
	long long d,x,y;

	cin>>n>>m>>d;
	vector<long long>a(n),b(m);

	for(int i=0;i<n;i++)cin>>a[i];
	for(int i=0;i<m;i++)cin>>b[i];
	sort(a.begin(),a.end());
	sort(b.begin(),b.end());

	while(true){
		if((n==0)||(m==0)){
			cout<<-1<<endl;
			return 0;
		}
		x=a.back(),y=b.back();
		if(abs(x-y)<=d){
			cout<<(x+y)<<endl;
			return 0;
		}
		if(x>y)a.pop_back(),n--;
		else b.pop_back(),m--;
	}

	return 0;
}

posted:
last update: