[测试题]数组(array)
Description
Input
Output
Sample Input1
3 2 7
5 4 2
Sample Output1
999999732
Sample Explanation1
Sample Input2
5 3 1
5 4 3 5 5
Sample Output2
0
Sample Explanation2
Hint
题解
由于负数是肯定小于正数的,我们首先想到的就是将乘积变成负数。我们可以统计输入的负数个数。
那么会有两种情况:
$(i)$无论怎么变变不了负数,这个时候我们将所有数取绝对值。
我们需要使乘积最小,这时只需要将绝对值最小的数减小即可。
证明:
假设有四个正整数$a_1,a_2,a_3,a_4$,满足$a_1<a_2<a_3<a_4$。需要减去$x$。
我们取极端情况若$a_1-x$:
原式$=(a_1-x)*a_2*a_3*a_4$
$=a_1*a_2*a_3*a_4-x*a_2*a_3*a_4$
若$a_4-x$:
原式$=a_1*a_2*a_3*(a_4-x)$
$=a_1*a_2*a_3*a_4-x*a_1*a_2*a_3$
由于$-x*a_2*a_3*a_4<-x*a_1*a_2*a_3$
显然得证。
$(ii)$可以变成负数,我们变完负数后同样将所有数取绝对值。
既然已经是负数了,那我们只需所有的数的绝对值积最大即可。
证明同上,只是改变了加减。
所以我们只需要用小根堆维护绝对值最小的数即可。
我是用两个堆分别维护正数和负数。同时注意不要边减边取模,因为保存的是绝对值,和负数直接取模不同。
详见代码。
1 #include<map> 2 #include<ctime> 3 #include<cmath> 4 #include<queue> 5 #include<stack> 6 #include<vector> 7 #include<string> 8 #include<cstdio> 9 #include<cstring> 10 #include<cstdlib> 11 #include<iostream> 12 #include<algorithm> 13 #define LL long long 14 #define RE register 15 #define IL inline 16 using namespace std; 17 const LL N=2e5; 18 const LL MOD=1e9+7; 19 20 priority_queue<LL, vector<LL>, greater<LL> >a,b; 21 LL n,k,x,ai; 22 LL cnt; 23 bool flag; 24 IL void print() 25 { 26 LL sum=1; 27 while (!a.empty()) 28 { 29 LL tmp=-a.top()%MOD;a.pop(); 30 sum=(sum*tmp)%MOD; 31 } 32 while (!b.empty()) 33 { 34 LL tmp=b.top()%MOD;b.pop(); 35 sum=(sum*tmp)%MOD; 36 } 37 printf("%lld\n",(sum+MOD)%MOD); 38 exit(0); 39 } 40 IL void cuta() 41 { 42 if (a.top()/x+(bool)(a.top()%x)>=k) 43 { 44 LL tmp=a.top();a.pop(); 45 tmp=(tmp-(LL)k*(LL)x/*%MOD*/)/*%MOD*/; 46 a.push(tmp); 47 print(); 48 } 49 else 50 { 51 LL tmp=a.top();a.pop(); 52 tmp=(tmp-(LL)(a.top()/x+(bool)(a.top()%x))*(LL)x)/*%MOD*/; 53 k-=a.top()/x+(bool)(a.top()%x); 54 b.push(-tmp); 55 } 56 } 57 IL void cutb() 58 { 59 if (b.top()/x+(bool)(b.top()%x)>=k) 60 { 61 LL tmp=b.top();b.pop(); 62 tmp=(tmp-(LL)k*(LL)x/*%MOD*/)/*%MOD*/; 63 b.push(tmp); 64 print(); 65 } 66 else 67 { 68 LL tmp=b.top();b.pop(); 69 tmp=(tmp-(LL)(b.top()/x+(bool)(b.top()%x))*(LL)x)/*%MOD*/; 70 k-=b.top()/x+(bool)(b.top()%x); 71 a.push(-tmp); 72 } 73 } 74 IL LL getnum() 75 { 76 if (a.empty()) {flag=0;LL tmp=b.top();b.pop();return tmp;} 77 if (b.empty()) {flag=1;LL tmp=a.top();a.pop();return tmp;} 78 if (a.top()>b.top()) {flag=0;LL tmp=b.top();b.pop();return tmp;} 79 {flag=1;LL tmp=a.top();a.pop();return tmp;} 80 } 81 82 int main() 83 { 84 scanf("%lld%lld%lld",&n,&k,&x); 85 for (RE LL i=1;i<=n;i++) 86 { 87 scanf("%lld",&ai); 88 if (ai<0) cnt++,a.push(-ai); 89 else b.push(ai); 90 } 91 if (cnt%2==0) 92 { 93 if (cnt==0) cutb(); 94 else if (cnt==n) cuta(); 95 else 96 { 97 if (a.top()>=b.top()) cutb(); 98 else cuta(); 99 } 100 } 101 if (!k) print(); 102 while (k--) 103 { 104 LL tmp=getnum(); 105 tmp=(tmp+x)/*%MOD*/; 106 if (flag) a.push(tmp); 107 else b.push(tmp); 108 } 109 print(); 110 return 0; 111 }
博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/NaVi-Awson/,否则你会终生找不到妹子!!!