【题目大意】:给你一些数,你每次操作可以选择一个数加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; }