codeforces721D
sol:思考过后得到 对于a>b>0 有a*b>(a-x)*b>a*(b-x)
维护一个优先队列,每次使得绝对值最小的数字绝对值变大就行了
#include <bits/stdc++.h> using namespace std; #define int long long typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();} while(isdigit(ch)) {s=(s<<3)+(s<<1)+(ch^48); ch=getchar();} return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) {putchar('-'); x=-x;} if(x<10) {putchar(x+'0'); return;} write(x/10); putchar((x%10)+'0'); } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') const int N=200005,inf=2147483645; inline void sb(); inline void QAQ(); int n,m,opt; int a[N]; struct node { int v,id; inline bool operator<(const node tmp)const { return abs(tmp.v)<abs(v); } }; priority_queue<node>wwx; inline void sb() { int i; node tmp; while(m--) { tmp=wwx.top(); wwx.pop(); if(tmp.v<0) tmp.v-=opt; else tmp.v+=opt; wwx.push(tmp); } while(wwx.size()) { tmp=wwx.top(); wwx.pop(); a[tmp.id]=tmp.v; } QAQ(); } inline void QAQ() { int i; for(i=1;i<=n;i++) W(a[i]); return; } signed main() { freopen("codeforces.in","r",stdin); int i,ql=0; R(n); R(m); R(opt); for(i=1;i<=n;i++) { R(a[i]); ql+=(a[i]<0)?1:0; } for(i=1;i<=n;i++) wwx.push((node){a[i],i}); node tmp=(node){0,0}; if(!(ql&1)) { tmp=wwx.top(); wwx.pop(); if(tmp.v<0) { if(tmp.v+m*opt>0) { m-=(-tmp.v)/opt+1; tmp.v+=opt*((-tmp.v)/opt+1); wwx.push(tmp); sb(); } else { tmp.v+=m*opt;; wwx.push(tmp); m=0; sb(); } } else if(tmp.v>=0) { if(tmp.v-m*opt<0) { m-=tmp.v/opt+1; tmp.v-=opt*(tmp.v/opt+1); wwx.push(tmp); sb(); } else { tmp.v-=m*opt; wwx.push(tmp); m=0; sb(); } } } else { sb(); } return 0; }
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!