HDU-4342 History repeat itself 二分

先二分找到这个非平方数,然后对一个一个区间进行求和的预处理。要注意边界问题。

代码如下:

#include <cstdlib>

#include <cstdio>

#include <cmath>

#include <algorithm>

using namespace std;



typedef long long Int;



Int N, num;



long long int sum[1000005];



Int bsearch(Int l, Int r) {

    Int mid, left;

    while (l <= r) {

        mid = (l + r) >> 1;

        left = mid - (int)floor(sqrt(double(mid)));

        if (N > left) {

            l = mid + 1;

        }

        else {

            r = mid - 1;

        }

    }

    return l;

}



void pre()

{

    int lim = 1 << 16;

    for (int i = 1; i <= lim; ++i) {

        sum[i] = sum[i-1]+1LL * (2*i+1) * i;

    }

}



int main()

{

    Int T, pos, s;

    long long int ans;

    pre();

    scanf("%I64d", &T);

    while (T--) {

        ans = 0;

        scanf("%I64d", &N);

        pos = bsearch(1, 1LL<<32);

        s = (int)floor(sqrt(double (pos)))-1;

        ans += (s+1)*(pos - (s+1)*(s+1)+1);

        printf("%I64d %I64d\n", pos, ans + sum[s]);

    }

    return 0;

}

你可能感兴趣的:(history)