• Sum of Remainders(数学题)


     

    F - Sum of Remainders

    Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

    Description

    Calculate the value of the sum: n mod 1 + n mod 2 + n mod 3 + ... + n mod m. As the result can be very large, you should print the value modulo 109 + 7 (the remainder when divided by 109 + 7).

    The modulo operator a mod b stands for the remainder after dividing a by b. For example 10 mod 3 = 1.

    Input

    The only line contains two integers n, m (1 ≤ n, m ≤ 1013) — the parameters of the sum.

    Output

    Print integer s — the value of the required sum modulo 109 + 7.

    Sample Input

    Input
    3 4
    Output
    4
    Input
    4 4
    Output
    1
    Input
    1 1
    Output

    0

    //给你两个数n,m,问你n % 1 + n % 2 + … + n% m为几

    这个题目的思路是,和为 n * m - sum ( [ n / i ] * i )  ,[ ] 是向下取整,i 从(1--- m) 

    具体是:

    前面的 n*m 肯定就这样了

    主要是后面的 :将 [ n / i ] 相同的做一个区间,用求和公式去节省时间

    i 从 1 --- sqrt (n) ;

    l = n / ( i + 1 ) + 1 , r =  n / i ; // 这就是一个个的区间

    比如 n = 20 , m = 20

    i=1 -->  l=11, r=20   n / (11---20) 都是等于 1 

    i=2 -->  l=7, r=10     n / (7---10) 都等于2

    i=3 -->  l=r=6

    i=4 -->  l=r=5

    注意一些特殊情况,看注释

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 using namespace std;
     5 
     6 #define ll __int64
     7 const ll MOD=1e9+7;
     8 
     9 int main()
    10 {
    11     ll n,m;
    12     scanf("%I64d%I64d",&n,&m);
    13     ll ans=(n%MOD)*(m%MOD)%MOD;
    14     ll temp=0,las=m+1;//记录哪些数没被减
    15     m=min(n,m);//n 余大于 n 的都等于 n
    16     ll nn=(ll)sqrt(n*1.0);
    17     for (ll i=1;i<=nn;i++)
    18     {
    19         ll l = n/(i+1)+1;
    20         ll r = n/i;
    21 
    22         r=min(r,m);//可能 r 比 m 大
    23         if (l>r) continue;
    24 
    25         las=min(las,l);
    26 
    27         ll s1=l+r , s2 =(r-l+1);//这里高斯求和有个坑,要先判断哪个数可以除2,再乘
    28         if (s1%2==0) s1/=2;     //直接用公式也不对,会超出ll限制
    29         else s2/=2;
    30         s1%=MOD;s2%=MOD;
    31         s1=(s1*s2)%MOD;
    32         s1=s1*i%MOD;
    33         temp=(temp+s1)%MOD;
    34     }
    35     ans=(ans+MOD-temp)%MOD;
    36     for (ll i=1;i<las;i++) //剩下的没被减得数,将n余之为0的最大整数减去
    37     {
    38         temp=n/i%MOD*i%MOD;
    39         ans=(ans+MOD-temp)%MOD;
    40     }
    41     printf("%I64d
    ",ans);
    42 
    43     return 0;
    44 }
    View Code
  • 相关阅读:
    find 指定不删除目录文件
    ORACLE 中 START WITH CONNECT BY PRIOR 用法(用于父子关系的数据表查询)
    ORACLE隔离级别与脏读/不可重复读/幻读的关系以及SELECT FOR UPDATE用法
    ORACLE查询最终阻塞者进程脚本
    01磁盘原理 心得记录
    02RAID技术 学习心得
    04华为HyperReplication中的多时间片技术
    单片机的电源系统
    阴阳论
    03文件系统 学习心得
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/5932026.html
Copyright © 2020-2023  润新知