标签:Function 10 midl int HDU7106 ans midr check 三分
目录
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
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。