洛谷—— P2424 约数和

https://www.luogu.org/problem/show?pid=2424

题目背景

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。

 

 1 #include <cstdio>
 2 
 3 #define LL long long
 4 inline void read(LL &x)
 5 {
 6     x=0; register char ch=getchar();
 7     for(; ch>'9'||ch<'0'; ) ch=getchar();
 8     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 
 9 }
10 LL x,y,ans;
11 
12 int Presist()
13 {
14 //    freopen("A.in","r",stdin);
15 //    freopen("A.out","w",stdout);
16     read(x),read(y);
17     if(x>y) {LL tmp=x;x=y;y=tmp;} x--;
18     for(LL i=1;i<=y; ++i)
19         ans+=i*(y/i)-i*(x/i);
20     printf("%I64d",ans);
21     return 0;
22 }
23 
24 int Aptal=Presist();
25 int main(int argc,char *argv[]){;}
60,暴力算每个约数和

可以发现,有些约数的个数是相同的,考虑将它们一起算,

枚举相同约数个数的左边界,右边界=i/(i/l),等差数列Sn=(s1+sn)>>1;

 1 #include <cstdio>
 2 
 3 #define LL long long
 4 inline void read(LL &x)
 5 {
 6     x=0; register char ch=getchar();
 7     for(; ch>'9'||ch<'0'; ) ch=getchar();
 8     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 
 9 }
10 LL x,y,ans;
11 inline LL sum(LL a)
12 {
13     if(a<2) return 0;
14     LL ret=0,l=1,r=0;
15     for(; l<=a; l=r+1)
16     {
17         r=a/(a/l); 
18         ret+=(r-l+1)*(a/l)*(l+r)>>1;
19     }
20     return ret;
21 }
22 
23 int Presist()
24 {
25 //    freopen("A.in","r",stdin);
26 //    freopen("A.out","w",stdout);
27     read(x),read(y);
28     if(x>y) {LL tmp=x;x=y;y=tmp;}
29     printf("%lld",sum(y)-sum(x-1));
30     return 0;
31 }
32 
33 int Aptal=Presist();
34 int main(int argc,char *argv[]){;}

 

转载于:https://www.cnblogs.com/Shy-key/p/7575211.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值