余数求和

给出正整数n和k,计算j(n,k)=k mod 1 + k mod 2 + k mod 3 +⋯+ k mod n的值。其中
k mod i表示k除以i的余数。

例如j(5,3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5 = 0 + 1 + 0 + 3 + 3 = 7

输入

输入仅一行,包含两个整数n,k(1≤n,k≤10)。

输出

输出仅一行,即j(n,k)。

样例输入

5 3

样例输出

7

分析

余数公式

k mod i = k - (k // i) * i,其中//表示整数除法,在一个区间中k // i 是相等的, 那么计算就可以使用等差数列求和这个区间,减少运算次数,
因此,只要找到两个边界使得k//l=k//(l+1)=k//(l+2)=⋯=k//r,再逐一求和,左边界l从1开始,右边界r可以通过k / (k // l) 求得

代码

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    //
    // freopen("E:/Code/C++/untitled1/input.txt","r",stdin);
    // freopen("output.txt","w",stdout);


    ll n,k;
    cin >> n >> k;
    ll ans = n * k,l = 1,r = 0;  //初始化ans和左边界
    while (l <= n ) // 左边界不超出范围
    {
        if(k / l == 0) break;  // 左边界已经大于k的时候,余数都为k,不用继续计算了
        r = min(n,k/(k/l)); //右边界, 不能大于n
        ans -= (k / l) * (l + r)*(r - l + 1) / 2;  // (k / l) 是区间的定值, (l + r)是区间端点和,是等差数列的首项和尾项, (r - l + 1) 是项数
        l = r + 1; //更新左边界
    }
    cout << ans << '\n';

}
posted @   bakul  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示