这两天跟1008过不去额。。。老是被一些2b类型的错误卡。。。。
周六1008因为函数参数里一个long long的失误悲剧,周日的1008因为没有添加新生成的数到数组中一直WA。。。。这后台数据够强的~~
思路:如果有奇数个负数,找出最大的那个,一直往上调,到0为止,然后把尽可能把0变成1,然后尽可能把1变成2,2->3.。。。到最后剩下的m求pow(3,m/3)然后填到数组里排序(注意,一定要填到数组里,否则后面的步骤可能出错,我就在这里WA了n次。。。),然后如果m%3还剩1的话,就把数组中最小的一个数加1(知道为什么前面那步要先填到数组里了吧,就是这。。。),否则最后的结果乘2。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100100;
typedef long long llg;
const llg P = 1000000007;
int n, a[N];
llg m;
llg pow(llg a, llg b)
{
llg tmp = a%P, ans = 1;
while(b)
{
if(b & 1) ans = ans * tmp % P;
tmp = tmp*tmp % P;
b >>= 1;
}
return ans%P;
}
int main()
{
int T, Case = 0;
int ct, i;
llg ans;
freopen("data.txt", "r", stdin);
scanf("%d", &T);
while(T--)
{
scanf("%d%I64d", &n, &m);
for(i = 0; i < n; i++) scanf("%d", a+i);
sort(a, a+n);
for(i = ct = 0; i < n; i++)
{
ct += (a[i]<0);
if(a[i] >= 0) break;
}
if(ct & 1)
{
i--;
if(-a[i] <= m)
{
m += a[i];
a[i] = 0;
}
else
{
a[i] += m;
m = 0;
}
}
for(i = 0; i<n && m>0; i++)
if(a[i] == 0)
{
a[i]++;
m--;
}
for(i = 0; i<n && m>0; i++)
if(a[i] == 1)
{
a[i]++;
m--;
}
for(i = 0; i<n && m>0; i++)
if(a[i] == 2)
{
a[i]++;
m--;
}
ans = 1;
if(m >= 3)
{
a[n] = pow(3, m/3);
n++;
m %= 3;
}
sort(a, a+n);
if(m == 1)
{
for(i = 0; i < n; i++)
if(a[i] > 0)
{
a[i]++;
break;
}
}
else if(m == 2)
ans = ans * 2 % P;
for(i = 0; i < n; i++)
ans = ans * a[i] % P;
printf("Case %d: %I64d\n", ++Case, ans);
}
return 0;
}