题目描述
zc去参加抽奖活动,在抽奖箱里有n个球,每个球上写着一个数字。一次抽取两个球,得分为两个球上的数的乘积。为了中大奖,zc想要知道他能得到的最大得分为多少。
输入
第一行为T,代表样例数。(1<=T<=10)
其中每组样例,第一个数为n,代表球的数量,接下来n个数s1,s2…,sn,代表球上的数字。(2<=n<=1e5,-4e9<=bi<=4e9)

输出
每组样例输出一行,输出一个数,代表zc得到的最大得分。(保证最大得分不小于0)
样例输入

2
3
1 2 3
3
-1 0 1

样例输出

6
0

AC代码

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int M=;
ll aa[],bb[],sum[];
ll aa1[],bb1[],sum1[];
ll a[M];
int main()
{
ll n,T;
cin>>T;
while(T--)
{
cin>>n;
ll i,j=,k=,p=,l=,l1=,l2=,l3=,l4=,lp=;
memset(a,,sizeof(a));
memset(aa,,sizeof(aa));
memset(bb,,sizeof(bb));
memset(sum,,sizeof(sum));
memset(aa1,,sizeof(aa1));
memset(bb1,,sizeof(bb1));
memset(sum1,,sizeof(sum1));
for(i=;i<n;i++)
scanf("%lld",&a[i]);
ll Max1=-,Max2=-,Min1=,Min2=;
for(i=;i<n;i++)
{
if(Max1<a[i])
{
k=i;
Max1=a[i];
}
if(Min1>a[i])
{
p=i;
Min1=a[i];
}
}
for(i=;i<n;i++)
{
if(i!=k)
{
if(Max2<a[i])
Max2=a[i];
}
if(i!=p)
{
if(Min2>a[i])
Min2=a[i];
}
}
Min1=-Min1;
Min2=-Min2;
if(Max1==)
aa[]=;
if(!Max2)
bb[]=;
if(Min1==)
aa1[]=;
if(Min2==)
bb1[]=;
while(Max1)
{
aa[l1++]=Max1%;
Max1/=;
}
while(Max2)
{
bb[l2++]=Max2%;
Max2/=;
}
for(i=;i<l1;i++)
for(j=;j<l2;j++){
sum[i+j]+=aa[i]*bb[j];
l=i+j;
}
for(i=;i<l;i++)
{
ll w=sum[i];
sum[i]=w%;
sum[i+]+=w/;
}
while(Min1)
{
aa1[l3++]=Min1%;
Min1/=;
}
while(Min2)
{
bb1[l4++]=Min2%;
Min2/=;
}
for(i=;i<l3;i++)
for(j=;j<l4;j++){
sum1[i+j]+=aa1[i]*bb1[j];
lp=i+j;
}
for(i=;i<lp;i++)
{
ll w=sum1[i];
sum1[i]=w%;
sum1[i+]+=w/;
}
int flag=;
if(lp>l) flag=;
else
{
for(i=;i<;i++)
{
if(sum[i]<sum1[i])
{
flag=;
break;
}
}
}
if(flag)
{
for(;lp>=;lp--) printf("%lld",sum1[lp]);
printf("\n");
}
else
{
for(;l>=;l--) printf("%lld",sum[l]);
printf("\n");
} }
return ;
}
05-24 06:51