[CQOI2007]余数求和

大于k的部分直接加k
对于小于等于k的cnt个数 ans=cnt*k - Σ(k/i * i)
然后k/i在一段区间内不变,这段区间直接可以数列求和

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;

IL ll Read(){
    RG char c = getchar(); RG ll x = 0, z = 1;
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}

ll n, k, ans;

int main(RG int argc, RG char* argv[]){
    n = Read(); k = Read();
    if(n > k) ans = (n - k) * k, n = k;
    ans += n * k;
    for(RG ll l = 1, r = n; l <= n; l = r + 1){
        r = min(n, k / (k / l));
        ans -= (k / l) * (r - l + 1) * (l + r) >> 1;
    }
    printf("%lld\n", ans);
    return 0;
}
posted @ 2017-12-19 20:41  Cyhlnj  阅读(124)  评论(0编辑  收藏  举报