1.题目链接。题目大意:给定一个数组t,和a,b.求表达式a*t[i]*t[i]+b*t[j]的最大值,其中i!=j。
2.这个题之前区域赛模拟的时候写了一下,代码写的很乱,其实我们分析一下就知道,我们对数组排序,那么对于所有的a,b,不管是正数还是负数,它的最大值都一定是在特定的几个位置取到的。这几个位置就是排序之后的开始两个数,结尾的两个数和中间的四个数,注意这里中间的四个数有时候存在有时候不存在,因为当数据是既有正数又有负数的时候,才存在,当数据都同号的时候,其实取最值的点只有四个。所以我们不管那么多,直接把这些数据全部拿出来暴力,是可以过的。但是赛后想了想,完全没有必要。其实只需要维护第a*t[i]*t[i]的最大值和次大值,与b*t[i]的最大值和次大值。然后判断是不是在同一个点取到组合即可。代码如下:
#include<bits/stdc++.h>
#include<algorithm>
#define ll long long
using namespace std;
const ll N = 5e6 + 10;
ll tem[N];
#pragma warning(disable:4996)
int main()
{
ll T;
scanf("%lld", &T);
for (int t = 1; t <= T; t++)
{
ll n, a, b;;
scanf("%lld%lld%lld", &n, &a, &b);
for (int i = 0; i < n; i++)
{
scanf("%lld", &tem[i]);
}
//sort(tem, tem + n);
ll mmaxA=-2e18, mmaxA2=-2e18;
ll Ai=0, A2i=0;
ll mmaxB=-2e18, mmaxB2=-2e18;
ll Bi=0, B2i=0;
for (int i = 0; i < n; i++)
{
ll tem1 = a * tem[i] * tem[i];
if (tem1 > mmaxA)
{
mmaxA2 = mmaxA;
A2i = Ai;
mmaxA = tem1;
Ai = i;
}
else if (tem1 > mmaxA2)
{
mmaxA2 = tem1;
A2i = i;
}
ll tem2 = b * tem[i];
if (tem2 > mmaxB)
{
mmaxB2 = mmaxB;
B2i = Bi;
mmaxB = tem2;
Bi = i;
}
else if (tem2 > mmaxB2)
{
mmaxB2 = tem2;
B2i = i;
}
}
long long ans = 0;
if (Ai != Bi)
{
ans = mmaxA + mmaxB;
}
else
{
ans = max(mmaxA + mmaxB2, mmaxA2 + mmaxB);
}
printf("Case #%d: %lld\n", t, ans);
}
}