洛谷 P2424 约数和

题目背景

Smart最近沉迷于对约数的研究中。

题目描述

对于一个数X,函数f(X)表示X所有约数的和。例如:f(6)=1+2+3+6=12。对于一个X,Smart可以很快的算出f(X)。现在的问题是,给定两个正整数X,Y(X<Y),Smart希望尽快地算出f(X)+f(X+1)+……+f(Y)的值,你能帮助Smart算出这个值吗?

输入输出格式

输入格式:

 

输入文件仅一行,两个正整数X和Y(X<Y),表示需要计算f(X)+f(X+1)+……+f(Y)。

 

输出格式:

 

输出只有一行,为f(X)+f(X+1)+……+f(Y)的值。

 

输入输出样例

输入样例#1:
2 4
输出样例#1:
14
输入样例#2:
123 321
输出样例#2:
72543

说明

对于20%的数据有1≤X<Y≤105。

对于60%的数据有1≤X<Y≤1*107。

对于100%的数据有1≤X<Y≤2*109。

 

前面做过一个约数个数的问题 点击就送

这题就是求[l,r]的约数和

也就是 1~r 减 1~l-1的约数和

但是直接用上题方法会T成狗 

于是我们发现有些因子出现次数是相同的 

比如 若 n=8

那 1~8出现次数分别为 8 4 2 2 1 1 1 1

出现次数相同的区间右端点=n/(n/l)

我们可以把出现次数相同的一起算 (大佬说这叫乘法原理)

直接输出lld 出现了蜜汁错误 

于是改了输出优化

屠龙宝刀点击就送

#include <cstdio>
#include <cctype>

typedef long long LL;
LL x,y;
inline void Read(LL &x)
{
    register char ch=getchar();
    for(x=0;!isdigit(ch);ch=getchar());
    for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
}
LL solve(LL x)
{
    LL l=1,r,ret=0;
    for(;l<=x;l=r+1)
    {
        r=x/(x/l);
        ret+=x/l*(r+l)*(r-l+1)/2;
    }
    return ret;
}
void print(LL ans)
{
    if(ans/10) print(ans/10);
    putchar(ans%10+'0');
}
int Main()
{
    Read(x);
    Read(y);
    print(solve(y)-solve(x-1));
    return 0;
}
int sb=Main();
int main(int argc,char *argv[]){;}

 

posted @ 2017-09-22 15:16  杀猪状元  阅读(196)  评论(0编辑  收藏  举报