先二分找到这个非平方数,然后对一个一个区间进行求和的预处理。要注意边界问题。
代码如下:
#include#include #include #include 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;}