1. 程式人生 > >Codeforces Round #374 (Div. 2)-D Maxim and Array

Codeforces Round #374 (Div. 2)-D Maxim and Array

clu pan air rst main flag lap and class

題目大意:給你n個數,最多有k次操作,每次操作可以將一個任意一個數加上x或者減去x,問你經過k次操作

之後,滿足n個數乘積最小的改變後的序列。

思路:我們先考慮原序列由奇數個負數,那麽我們只要將n個數的絕對值全部加入優先隊列,然後每次操作取出

最小值,如果是負數能減去x,如果是正數加上x,這樣進行將會得到最優解。

  再考慮沒有負數是偶數個的情況,那麽我們如果n個數中的絕對值的最小值小於x*k,則我們將這個絕對值

最小的數變成反號,然後就變成了第一種情況。 如果n個數中的絕對值的最小值大於等於x*k,如果這個數是正

數則減去x*k,負數則加上x*k。

有0的情況需要特殊處理一下,細節比較多,不太好寫。

技術分享圖片
 1 #include<bits/stdc++.h>
 2 #define pii pair<long long,int>
 3 #define mk make_pair
 4 #define fi first
 5 #define se second
 6 #define ll long long
 7 using namespace std;
 8 const int N=2*1e5+5;
 9 int n;
10 long long a[N],k,x,cnt1=0,cnt2=0;
11 pii mn,_mn;
12 priority_queue<pii,vector<pii>,greater<pii> > Q;
13 int main() 14 { 15 mn.fi=1e9+10,_mn.fi=1e9+10; 16 mn.se=0,_mn.se=0; 17 scanf("%d%lld%lld",&n,&k,&x); 18 for(int i=1;i<=n;i++) 19 { 20 scanf("%lld",&a[i]); 21 if(a[i]<0) 22 { 23 cnt1++; 24 _mn=min(_mn,mk(-a[i],i));
25 } 26 else if(a[i]>0) mn=min(mn,mk(a[i],i)); 27 else cnt2++; 28 } 29 if(cnt2>k) 30 { 31 for(int i=1;i<=n;i++) printf("%lld ",a[i]); 32 return 0; 33 } 34 if(cnt2) 35 { 36 bool flag=false; 37 for(int i=1;i<=n;i++) 38 { 39 if(a[i]!=0) continue; 40 if(!(cnt1&1)) 41 { 42 a[i]-=x; 43 cnt1++; 44 } 45 else a[i]+=x; 46 k--; 47 } 48 } 49 if(!(cnt1&1)) 50 { 51 ll w=k*x; 52 if(mn.fi<=_mn.fi) 53 { 54 if(mn.fi<w) 55 { 56 cnt1++; 57 int u=(mn.fi+1)/x; 58 if((mn.fi+1)%x!=0) u++; 59 k-=u; 60 a[mn.se]-=u*x; 61 } 62 else a[mn.se]-=w,k=0; 63 } 64 else 65 { 66 if(_mn.fi<w) 67 { 68 cnt1--; 69 int u=(_mn.fi+1)/x; 70 if((_mn.fi+1)%x!=0) u++; 71 k-=u; 72 a[_mn.se]+=u*x; 73 } 74 else a[_mn.se]+=w,k=0; 75 } 76 } 77 if(cnt1&1) 78 { 79 for(int i=1;i<=n;i++) 80 { 81 if(a[i]==0) 82 { 83 a[i]+=x; 84 k--; 85 } 86 Q.push(mk(abs(a[i]),i)); 87 } 88 while(k--) 89 { 90 pii cur=Q.top(); Q.pop(); 91 if(a[cur.se]<0) a[cur.se]-=x; 92 else a[cur.se]+=x; 93 Q.push(mk(abs(a[cur.se]),cur.se)); 94 } 95 } 96 for(int i=1;i<=n;i++) printf("%lld ",a[i]); 97 puts(""); 98 return 0; 99 }
View Code

Codeforces Round #374 (Div. 2)-D Maxim and Array