HDU7106 Function(三分)
作者:互联网
目录
Description
\(f(x)=Ax^2g(x)+Bx^2+Cxg^2(x)+Dxg(x)\), 其中 \(g(x)\) 为 \(x\) 的数位之和,求 \(f(x)\) 的最小值(\(1<=x<=N\))
State
\(1<=T<=10^4\)
\(0<=|A|<=10^3,0<=|B|,|C|,|D|<=10^6,1<=N<=10^6\)
Input
2
1 2 3 4 100
4 3 2 1 100
Output
10
10
Solution
看到 \(x<=N\) 的条件,一看 \(N\) 又不大,要不是有 \(T\) 在那里摆着就可以枚举 \(g(x)=[1,54]\) 的所有情况了
这个式子已经确定是一个二次函数了,求最小值,三分求凹函数最小值,当然需要特判掉不是二次函数以及开口向下的情况
Code
int n, m, _, k;
//int a[N];
vector<int> v[60];
int calc(int x)
{
int ans = 0;
while(x) ans += x % 10, x /= 10;
return ans;
}
void init()
{
for(int i = 1; i <= 1e6; i ++){
v[calc(i)].pb(i);
}
}
ll check(ll x, ll A, ll B)
{
return A * x * x + B * x;
}
signed main()
{
//IOS;
ll a, b, c, d;
init();
rush(){
sll2(a, b); sll2(c, d); sd(n);
ll minn = 6e18;
for(int i = 1; i <= 54; i ++){
if(v[i].size() == 0) continue;
ll A = a * i + b, B = c * i * i + d * i;
int l = 0, r = upper_bound(v[i].begin(), v[i].end(), n) - v[i].begin() - 1;
ll ans = 6e18;
if(l > r) continue;
if(A <= 0){
ans = min(check(v[i][l], A, B), check(v[i][r], A, B));
minn = min(ans, minn);
continue;
}
while(r >= l){
int midl = l + (r - l) / 3;
int midr = r - (r - l) / 3;
if(check(v[i][midl], A, B) < check(v[i][midr], A, B)){
r = midr - 1;
ans = min(ans, check(v[i][midl], A, B));
}
else{
l = midl + 1;
ans = min(ans, check(v[i][midr], A, B));
}
}
minn = min(minn, ans);
}
pll(minn);
}
//PAUSE;
return 0;
}
标签:Function,10,midl,int,HDU7106,ans,midr,check,三分 来源: https://www.cnblogs.com/Segment-Tree/p/15322904.html