【BZOJ 1257】余数之和

题目描述

给出正整数 n k ,计算 ( k mod 1 ) + ( k mod 2 ) + ( k mod 3 ) + + ( k mod n ) 的值。 1 n , k 10 9

算法分析

将取模运算变换形式: k mod i = k k i × i ,则 i = 1 n k mod i = n × k × i = 1 n k i × i

注意到随着 i 的递增, k i 的值递减,而且有一段部分相同,可以证明不同的 k i 值有 O ( k ) 种,考虑将这一部分一次性单独处理。

可以 O ( 1 ) 计算出以 i 为起点的相同部分的终点 m i n { n , k k i } ,注意当分母 k i = 0 时会出错,这时应当特判终点为 n ,还有后面乘 i 的部分直接使用等差数列公式求解即可,时间复杂度 O ( k )

实现代码

#include <cstdio>
#include <algorithm>
typedef long long int ll;
int main() {
    ll n,k;
    scanf("%lld%lld",&n,&k);
    ll ans=n*k;
    for(int i=1;i<=n;++i) {
        ll end=k/i==0?n:std::min(n,k/(k/i));
        ans-=(k/i)*(i+end)*(end-i+1)/2;
        i=end;
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/WHZ2018/article/details/81252981