51nod 1225 余数之和


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的结果即可。

分析:
6-6/1*1
6-6/2*2
6-6/3*3
6-6/4*4
6-6/5*5
6-6/6*6

得到:

可以在 内讨论n的约数,及其对应的
局部是 i*等差数列

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const LL mod=1000000007;
LL power(LL a,LL p){
    LL ans=1;
    a=a%mod;
    while(p){
        if(p&1) ans=ans*a%mod;
        a=a*a%mod;
        p>>=1;
    }
    return ans;
}
int main()
{
    LL n;
    LL ni=power(2,mod-2);  //欧拉定理
    while(~scanf("%I64d",&n)){
        LL ans=((n%mod)*(n%mod))%mod;
        LL len=(LL)sqrt(1.0*n);
        for(LL i=1;i<=len;i++){
            if(i==n/i){
                // ans=(ans-n+mod)%mod;
                LL t=n/i*i;  //!!
                ans=((ans-t)%mod+mod)%mod;
                continue;
            }
            LL l_r=(n/i+n/(i+1)+1)%mod;
            LL num=(n/i-n/(i+1))%mod;
            LL temp=i*num%mod;
            temp=(temp*l_r%mod)*ni%mod;  // 逆元处理浮点问题
            temp=(temp+n/i*i%mod)%mod;
            ans=((ans-temp)%mod+mod)%mod;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值