题面:
You are given an array a consisting of n element a1, a2, ..., an. For each element ai you must find another element aj (i ≠ j), such that the summation of ai and aj mod (109 + 7) (i.e. (ai + aj) % (109 + 7)) is as maximal as possible.
Can you help judges by solving this hard problem?
Input:
The first line contains an integer T, where T is the number of test cases.
The first line of each test contains an integer n (2 ≤ n ≤ 105), where n is the size of the array a.
The second line of each test case contains n integers a1, a2, ..., an (0 ≤ ai < 109 + 7), giving the array a.
Output:
For each test case, print a single line containing n space separated elements, such that the ith element is the answer to the ith element in the array a (i.e. the maximum value of (ai + aj) % (109 + 7)).
Example:
Input:
2
3
1 2 3
2
1000000000 1000000000
Output:
4 5 5
999999993 999999993
Note:
As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printf instead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.
分析:
给你一堆数,让你求出其中每个数和数组中另一个任意数两两相加可以得到的最大值,依次输出。
把数组升序排列,用二分法以刚好能和num[i]相加等于mod的那个数为界,把数组分为两部分,前部分的数和num[i]相加值小于等于mod,后部分与num[i]相加值处于mod~mod+num[i]间,因为num[i]的范围是不超过mod的,所以如果能找到与num[i]相加小于mod的数,其中最大的那个就是答案(因为后部分所得值%mod后,最大得到num[i]),否则答案就在后半段,且为末尾的那个数。
比较麻烦的是因为要进行排序,但是输出还是要按照最初的下标顺序来输出,我的话只能想到用两个数组分开操作,大佬的话使用了pair,用second来存初始下标。
虽然最好是能用上二分,不过看了大佬的代码发现直接顺序遍历来找也是不会TLE的。
自己虽然明白了原理但是写得抓耳挠腮,看了大佬代码真的感慨人和人的差距……
附大佬AC代码。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int maxn = 100010;
const int mod = 1E9+7;
int t, n;
pair<ll, int>a[maxn];
ll ans[maxn];
void solve(){
memset(ans, -1, sizeof(ans));
sort(a+1, a+1+n);
int j = n;
for(int i = 1; i <= n; i++){
for(; j >= 1; j--){
if(i == j) continue;
if(a[i].first + a[j].first >= mod) continue;
ans[a[i].second] = a[i].first + a[j].first;
break;
}
if(ans[a[i].second] == -1){
ans[a[i].second] = (a[i].first + a[i == n ? n-1:n].first) %mod;
}
}
for(int i = 1; i <= n; i++) cout<<ans[i]<<' ';
cout<<endl;
}
int main(){
cin>>t;
while(t--){
memset(ans, 0, sizeof(ans));
cin>>n;
for(int i = 1; i <= n; i++){
ll mid;
scanf("%lld", &mid);
a[i] = make_pair(mid, i);
}
solve();
}
return 0;
}