【题目大意】:给你一些数,你每次操作可以选择一个数加1,或者新增一个数1,问最大乘积是多少。
【解题思路】:去年网络赛的题目了,当年是WA死在lld和I64d上。各种无语。题目好理解,把负数补足,然后尽可能凑3,贪心法。可以证明一下,设一两下数yy一下就可以
【代码】:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
using namespace std;
#define eps 1e-8
#define pi acos(-1.0)
#define inf 1<<30
#define linf 1LL<<60
#define pb push_back
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
#define lowbit(x) (x & (-x))
#define ll long long
#define MOD 1000000007
ll a[105000],b[105000],c[105000];
ll m,T,summ;
int n,bn,cn;
ll power_mod(ll x,ll n){
ll res=1;
while (n) {
if(n&1) res=res*x%MOD;
x=x*x%MOD;
n>>=1;
}
return res;
}
ll cnt(){
ll summ=1;
for (int i=0; i<bn; i++){
summ=summ*b[i];
summ=summ % MOD;
}
for (int i=0; i<cn; i++){
summ=summ*c[i];
summ=summ % MOD;
}
return summ%MOD;
}
int main(){
int T,cas=0;
cin >> T;
while (T--){
scanf("%d%I64d",&n,&m);
for (int i=0; i<n; i++){
scanf("%I64d",&a[i]);
}
summ=1;
bn=0;
cn=0;
for (int i=0; i<n; i++){
if (a[i]<0){
b[bn]=a[i];
bn++;
}
if (a[i]>=0){
c[cn]=a[i];
cn++;
}
}
sort(b,b+bn);
if (bn%2!=0 && m>0)
{
ll tmp=0-b[bn-1];
if (m>=tmp) {bn--; c[cn]=0; cn++; m=m-tmp;}
else {b[bn-1]=b[bn-1]+m; m=0;}
}
for (int i=0; i<cn; i++){
if (c[i]==0 && m>=1) {c[i]++; m--;}
}
for (int i=0; i<cn; i++){
if (c[i]==1 && m>=1) {c[i]++; m--;}
}
for (int i=0; i<cn; i++){
if (c[i]==2 && m>=1) {c[i]++; m--;}
}
sort(c,c+cn);
if (m<=0){
summ=cnt()%MOD;
cas++;
printf("Case %d: %I64d\n",cas,summ%MOD);
}
else{
if (m%3==1 && m!=1){
m=m-4;
summ=power_mod(3,m/3)%MOD;
summ=summ*4%MOD;
}
else
if (m%3==1 && m==1) c[0]++;
else
if (m%3==2){
m=m-2;
summ=power_mod(3,m/3)%MOD;
summ=summ*2%MOD;
}
else if (m%3==0) summ=power_mod(3,m/3)%MOD;
summ=summ*cnt()%MOD;
cas++;
printf("Case %d: %I64d\n",cas,summ%MOD);
}
}
return 0;
}