模和最大
Description
有个数组a, 对于每个a[i],你要找到一个a[j] (i != j) ,使得 (a[i] + a[j]) % p最大。
Input
输入第一行两个整数n,p。
第二行n个整数a[i]。
2 <= n <= 1e6.
2 <= p <= 1e9.
a[i] < p.
Output
一行输出n个整数,空格分开,最后一个数后面不要有空格。
Sample Input 1
5 7
2 3 3 4 5
Sample Output 1
6 6 6 6 2
具体看注释。
AC代码:
#include
using namespace std;
const int maxn = 1e6 + 10;
int a[maxn];
int b[maxn];
int main() {
int n, p;
scanf("%d%d", &n, &p);
for(int i = 1; i <= n; i ++){
scanf("%d", &a[i]);
b[i] = a[i];
}
sort(b + 1, b + n + 1);
int index;
for(int i = 1;i <= n;i ++){
index = lower_bound(b + 1,b + n + 1,p - a[i]) - b - 1; ///每一次寻找最后一个小于a[i] 的数
if(index > 0 && b[index] != a[i]) printf("%d",a[i] + b[index]); ///如果找到,且 b[index] != a[i] 即 排除了 i == j 的情况,直接输出
else if(index > 0 && b[index] == a[i]){ ///找到了,但是有可能找的就是自己
if(index > 1) printf("%d",b[index-1] + a[i]); ///如果index > 1, index 左的数 + a[i] 一定最大
else printf("%d",(b[n-(a[i] == b[n])] + a[i]) % p); /// == 1, index 位置左边没有数,直接加上最后的一个数,↓
} ///同时要判断 a[i] 是不是与 最后一个数相等 如果相等,就需要再次向前移一位,排除 选到 a[i] 自己的情况
else printf("%d",(b[n-(a[i] == b[n])] + a[i]) % p); ///找不到一个小于a[i] 的数, 与上同理
if(i != n) printf(" ");
}
printf("
");
return 0;
}
下面的记录给自己看的 QAQ.... 看看自己多蠢...
同理, lower_bound() 也可以直接寻找 是否存在 p - a[i] - 1, 如果存在,则可以直接输出 p - 1, 不过情况更为复杂一点。
设 lower_bound() 返回的值是 index, 当然 首先需要判断 b[index] 是否 等于 p - a[i] - 1, 还需要判断 a[i] 是否 等于 p - a[i] - 1
,要排除 选到自身的情况。 还需要判断 是否能寻找到 >= p - a[i] - 1 的数, 寻找不到就直接输出(a[i] + b[n - (a[i] == b[n])]) % p , 其中 -(a[i] == b[n]) 与上述理由相同。 最麻烦的就是 寻找到的是 >p - a[i] - 1 的位置, 需要判断 index 是否在首位 是否在 第二位。
举个栗子。
5 10
1 2 3 7 9
以及
5 10
9 8 7 3 9
AC代码:
///下标从 0 开始!!
#include
using namespace std;
const int maxn = 1e6 + 10;
int a[maxn];
int b[maxn];
int main() {
int n, p;
scanf("%d%d", &n, &p);
for(int i = 0; i < n; i ++)
scanf("%d", &a[i]),
b[i] = a[i];
sort(b, b + n);
int index;
for(int i = 0; i < n; i ++) {
index = lower_bound(b, b + n, p - a[i] - 1) - b;
if(index == n) printf("%d", (a[i] + b[n - 1 - (a[i] == b[n-1])]) % p);
else if(b[index] == p - a[i] - 1) {
if(a[i] != p - a[i] - 1) printf("%d", p - 1);
else {
if(b[index + 1] == a[i]) printf("%d", p - 1); ///出现 相等的情况, 也有可能 后面还有一位 a[] == p - a[i] - 1, 当然 此个 a 是最优
else if(index != 0) printf("%d", b[index - 1] + a[i]);
else printf("%d", (a[i] + b[n - 1-(a[i] == b[n-1])]) % p);
}
} else {
if(index == 0){
printf("%d",(a[i] + b[n-1-(a[i] == b[n-1])]) % p);
}
else {
if(index == 1){
if(b[index-1] == a[i]) printf("%d",(a[i] + b[n-1]) % p);
else printf("%d",(a[i] + b[index-1]) % p);
}
else printf("%d",max((a[i] + b[n-1-(a[i] == b[n-1])]) % p,(a[i] + b[index-1-(a[i] == b[index - 1])]) % p));
}
}
if(i != n - 1)printf(" ");
}
printf("
");
return 0;
}