BZOJ 1257: [CQOI2007]余数之和 数论专题第十四题

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/88874290

title

BZOJ 1257
Description

给出正整数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

Input

输入仅一行,包含两个整数n, k。
1<=n ,k<=10^9

Output

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

Sample Input

5 3

Sample Output

7

analysis

用了一个看起来比较奇怪的方法
首先 x m o d &ThinSpace;&ThinSpace; i = x ( i n t ) ( x / i ) i x \mod i = x – (int)(x / i) * i ,这个很好YY吧
然后可以找出每个 ( i n t ) ( x / i ) (int)(x / i) 相等的一段用等差数列求和来做。
可以证明最多分成 s q r t ( n ) sqrt(n) 段——摘自hzwer

然而我是看《算阶》,再加上邱宇的讲解,嗯,就写出来了。。。。。

code

#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}
int main()
{
    long long n,k,ans=0;
    read(n);read(k);
    ans=n*k;
    for (int x=1,gx; x<=n; x=gx+1)
    {
        gx=k/x?min(k/(k/x),n):n;
        ans-=(k/x)*(x+gx)*(gx-x+1)/2;
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/88874290