大家都说这题水然而我好像还是调了有一会儿……不过暴力真的很良心,裸的暴力竟然还有60分。
打一张表出来,就会发现数据好像哪里有规律的样子,再仔细看一看,就会发现k/3~k/2为公差为2的等差数列,k/2~之后为公差为1的等差数列,于是我们就可以利用高斯求和快速求解啦。自认为代码是能够看得的...
#include <bits/stdc++.h> using namespace std; #define LL long long #define int long long LL ans; int p, x = 10, n, m, k, base, skipper; LL Get_sum()//高斯求和,从p项开始公差为x { int y = x - 1; int base = (k % p); int end = max(base % y, base - (m - p) * y); skipper = ((base - end) / y) + 1; return ((LL)(base + end) * (LL)skipper) >> 1; } void init()//分段设x值 { if(k > 1000000) x = 1555; else if(k > 5000000) x = 600; else if(k > 300000) x = 100; else if(k > 5000) x = 50; else x = 2; } signed main() { scanf("%lld%lld", &n, &k); m = min(n, k); init(); for(p = 1; p <= m; p ++) { if(p == (k / x) + 1) { ans += Get_sum(); p += (skipper - 1);//统计加了多少项 x -= 1; } else ans += (k % p); } if(n > k) ans += (LL) (n - k) * (LL) (k); printf("%lld", ans); return 0; }