main
黄海 2 years ago
parent 5de71118eb
commit 28da7062e5

@ -114,17 +114,16 @@ using namespace std;
#define int long long
#define endl "\n"
// 数论分块模板题,是很多题的基础,需要背诵
// j(n,k)=k%1+k%2+k%3+…+k%n
int n, k, l, r;
int ans;
signed main() {
cin >> n >> k;
ans = n * k; // 看题解的推导公式
for (l = 1; l <= n; l = r + 1) { // 枚举左端点,每次跳着走下次的位置就是本次r的位置+1
if (k / l == 0) break; // 1、当k/l=0的时候显然这段以及后面有单调性已经没有贡献了可以 break。
r = min(k / (k / l), n); // 2、注意右端点和n取个min因为>n没有贡献了。
ans -= (k / l) * (l + r) * (r - l + 1) / 2; // 等差数列求和左到右边界内是公差为1的等差数列首项+末项 乘以 项数 除以2
if (k / l == 0) break; // 1、当k/l=0的时候比如3/4=0,3/5=0,3/6=0...,以后就都是0不用再往后算了无贡献
r = min(k / (k / l), n); // 2、注意右端点和n取个min>n没有贡献
ans -= (k / l) * (l + r) * (r - l + 1) / 2;
// 等差数列求和:首项:l,末项:r.项数:(r-l+1),根据公式推导k/l = 块内值
}
cout << ans << endl;
}

Loading…
Cancel
Save