51nod 1225 余数之和 数论

1225 余数之和

题目连接:

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1225

Description

F(n) = (n % 1) + (n % 2) + (n % 3) + ...... (n % n)。其中%表示Mod,也就是余数。
例如F(6) = 6 % 1 + 6 % 2 + 6 % 3 + 6 % 4 + 6 % 5 + 6 % 6 = 0 + 0 + 0 + 2 + 1 + 0 = 3。
给出n,计算F(n), 由于结果很大,输出Mod 1000000007的结果即可。

Input

输入1个数N(2 <= N <= 10^12)。

Output

输出F(n) Mod 1000000007的结果

Sample Input

6

Sample Output

3

Hint

题意

题解:

余数 = n - n/i*i

很显然n/i只会有n的因子个数那么多

而且n/i在连续的一段区间内都是一样的。

这个用一个等差序列去维护i就好了

然后就可以在sqrtn的复杂度解决这道题了。

代码

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
long long quickpow(long long  m,long long n,long long k)//返回m^n%k
{
    long long b = 1;
    while (n > 0)
    {
          if (n & 1)
             b = (b*m)%k;
          n = n >> 1 ;
          m = (m*m)%k;
    }
    return b;
}
long long mul(long long a,long long b)
{
    if(a>=mod)a%=mod;
    if(b>=mod)b%=mod;
    a=a*b;
    if(a>=mod)a%=mod;
    return a;
}
int main()
{
    long long n;
    cin>>n;
    long long ans=0;
    for(int i=1;i<=sqrt(n);i++)
    {
        if(n/i==i)
        {
            long long temp=n/i*i;
            ans=(ans+n-temp+mod)%mod;
            continue;
        }
        long long r=n/i;
        long long l=n/(i+1)+1;
        long long num=mul(mul(mul((r+l),quickpow(2,mod-2,mod)),(r-l+1)),i);
        //cout<<mul(n,r-l+1)<<" "<<num<<" "<<i<<" "<<r<<" "<<l<<endl;
        ans=(ans+mul(n,r-l+1)-num+mod)%mod;
        ans=(ans+n-mul(n/(n/i),(n/i))+mod)%mod;
    }
    cout<<ans<<endl;
}

你可能感兴趣的:(51nod 1225 余数之和 数论)