码迷,mamicode.com
首页 > 其他好文 > 详细

URAL 1948 H - The Robot on the Line 二分 + 数学

时间:2016-09-05 09:06:18      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

给定一条二次函数 f (x) = a * x * x + b * x + c

求一个最小的k,使得f(x) + f(x + 1) + f(x + 2) ..... + f(x + k - 1) 不等于 0 恒成立。

首先把参数统一写成 x + t这样的形式,然后带入去

化简有:a*x*x + (2*a*t+b)*x + a*t*t+b*t+c //现在的t是从0--k-1

列出k个式子,求和(简单的数列求和)。然后就得到一条关于x的二次函数,用判别式判断即可。

为什么能二分?

因为单调。化简后可以看到B*B - 4*A*C。k越大,<0就越成立。因为4*A*C有k的项且指数都比较高。所以这个判断是单调的。

则二分即可。

数字很大 啊。用double居然没爆。应该用到了1e100。double犀利啊

技术分享
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
LL a, b, c;
bool check (LL t) {
    double k = (double)t;
    double B = (b + 2 * a * (k - 1) + b) * k / 2.0;
    double C = a * (k - 1) * (k) * (2 * (k - 1) + 1) / 6 + (k - 1) * k / 2 * b + k * c;
    double A = k * a;
//    cout << B << " " << C << " " << A << endl;
    return B * B < 4 * A * C;
}
void work () {
    cin >> a >> b >> c;
//    cout << a << " " << b << " " << c << endl;
    LL begin = 1;
    LL end = 1e18;
//    cout << check (9) << endl;
    while (begin <= end) {
        LL mid = (begin + end) >> 1;
//        cout << mid << endl;
        if (check (mid)) { //mid是满足条件的,就是方程无解的
//            cout << " ***" << endl;
            end = mid - 1;
        } else {
            begin = mid + 1;
        }
    }
    if (begin > 1e18) {
        printf ("Infinity\n");
    } else {
        cout << begin << endl;
    }
    return ;
}

int main () {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    int t;
    cin >> t;
    while (t--) work ();
    return 0;
}
View Code

 

URAL 1948 H - The Robot on the Line 二分 + 数学

标签:

原文地址:http://www.cnblogs.com/liuweimingcprogram/p/5841059.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!