HDU7106 Function(思维+二分)

Posted KaaaterinaX

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU7106 Function(思维+二分)相关的知识,希望对你有一定的参考价值。

Function
这个题首先思路就很神奇,我还是太菜了一下也没想到。

观察到g(x)的取值范围很小,可以考虑枚举g(x)的取值,然后得到一个系数确定的抛物线,运用二分可以算出最小值。

但是!!

我按照这个思路,对抛物线进行分情况讨论,结果wa了一上午,why??

————对称轴存在误差。

二分传入的参数是整型的,但是对称轴的值很可能是个小数。所以建议枚举对称轴附近的几个点,来避免精度带来的误差。

ac代码如下:

vector<ll>G[100];
inline void init(){
    for(int i=1;i<=1e6;i++){
        int j=i;
        int x=0;
        while (j){
            x+=j%10;
            j/=10;
        }
        G[x].push_back(i);
    }
}

ll a,b,c,d,n;
inline ll f(ll i,ll x){
    return a*x*x*i+b*x*x+c*x*i*i+d*x*i;
}
inline int bin(int l0,int r0,int i,ll n){
    //n is the upper_bound
    int l=l0,r=r0;
    int res=-1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(G[i][mid]<=n){
            res=mid;
            l=mid+1;
        }
        else r=mid-1;
    }
    return res;
}
int main() {
    int t;
    scanf("%d",&t);
    init();
    while(t--){
        scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&n);
        ll ans=LINF;
        for(ll i=1;i<=54;i++){
            if(!G[i].size()) continue;
            //先找出n在这个数组的最大下标
            int up=bin(0,(int)G[i].size()-1,(int)i,n);
            if(up==-1) continue;//如果n不在这一组的范围内
            //判断开口方向
            ll A=a*i+b;
            if(A<=0){
                //如果开口向下,或者是一条直线
                ll d1=f(i,G[i][0]);
                ll d2=f(i,G[i][up]);
                ans=min(ans,min(d1,d2));
            }
            else{
                //如果开口向上
                ll dd=-((c*i*i+d*i)/(2*(a*i+b)));
                int x1=bin(0,up,(int)i,dd);
                if(x1==-1) x1=0;
                for(int j=max(0,x1-4);j<=min(up,x1+4);j++){
                    //枚举对称轴附近的几个点
                    ans=min(ans,f(i,G[i][j]));
                }
            }
        }
        printf("%lld\\n",ans);
    }
    return 0;
}

以上是关于HDU7106 Function(思维+二分)的主要内容,如果未能解决你的问题,请参考以下文章

HDU7106 Function(思维+二分)

HDU7106 Function(思维+二分)

HDU6038-Function-数学+思维-2017多校Team01

HDU 6276 Easy h-index(思维+二分/前缀和)

HDU 5936 Difference(思维+二分)——2016年中国大学生程序设计竞赛(杭州)

HDU 6216 A Cubic number and A Cubic Number数学思维+枚举/二分