函数 - 贪心
题面

题解
其实就是一个贪心,可以用优先队列之类的实时存下一步的最小方案。
但我由于没有仔细读题而爆零了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#define LL long long
using namespace std;
inline LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9'){x = x * 10 + s - '0';s = getchar();}
return x * f;
}
struct it{
LL i,x;
it(){i = x = 0;}
it(LL I,LL X){i = I;x = X;}
}d[100005];
LL n,m,i,j,s,o,k;
LL a[100005],b[100005],c[100005];
LL I,J;
bool flag;
LL js(LL i,LL x) {
return a[i] *1ll *x *1ll *x + b[i] *1ll* x + c[i]*1ll;
}
LL check(LL j) {
return js(I,j);
}
LL delta(LL i,LL x) {
LL no = js(i,x);
LL l = js(i,x - 1ll) - no;
LL r = js(i,x + 1ll) - no;
if(x - 1ll < 1ll) l = 1e18;
return (flag ? l:r);
}
bool operator < (it a,it b) {
return delta(a.i,a.x) > delta(b.i,b.x);
}
priority_queue<it> p;
LL solve(LL l,LL r) {
if(l >= r - 2ll) {
LL ans = r;
LL minn = check(r);
LL min2;
if((min2 = check(l)) < minn) ans = l,minn = min2;
if(check((l + r) / 2ll) < minn) ans = (l + r) / 2ll;
return ans;
}
LL mid1 = (l + l + r) / 3ll,mid2 = (l + r + r) / 3ll;
if(check(mid1) < check(mid2)) return solve(l,mid2);
return solve(mid1,r);
}
int main() {
freopen("function.in","r",stdin);
freopen("function.out","w",stdout);
n = read();m = read();
LL ans = 0;
for(int i = 1;i <= n;i ++) {
a[i] = read();b[i] = read();c[i] = read();
I = i;
LL x = solve(1,200000);
x = max(1ll,x);
m -= x;
// printf("%d: %d\n",i,x);
ans += js(i,x);
d[i] = it(i,x);
// cout<<ans<<endl;
}
if(m > 0) {
flag = 0;
for(int i = 1;i <= n;i ++) p.push(d[i]);
while(m > 0) {
it t = p.top();
p.pop();
ans += delta(t.i,t.x);
// printf("%lld %lld\n",ans,delta(t.i,t.x));
p.push(it(t.i,t.x + 1ll));
m --;
}
}
else if(m < 0) {
flag = 1;
for(int i = 1;i <= n;i ++) p.push(d[i]);
while(m < 0) {
it t = p.top();
p.pop();
ans += delta(t.i,t.x);
// printf("%lld %lld\n",ans,delta(t.i,t.x));
p.push(it(t.i,t.x - 1ll));
m ++;
}
}
printf("%lld\n",ans);
return 0;
}

浙公网安备 33010602011771号