约数和

题目描述 Description

给你一个数N,需要你算出这个数所有约数的和。(N的约数指能整除N的正整数),例如12的约数有1,2,3,4,6,12。所以约数和为1+2+3+4+6+12=28。

输入描述 Input Description

本题有多组数据,第一行一个T,表示有T组数据;下面T行,每行一个正整数N,表示要处理的数。

输出描述 Output Description

T行,每行一个正整数,表示输入中对应的数的约数和。

样例输入 Sample Input

1

12 

样例输出 Sample Output

28

数据范围及提示 Data Size & Hint

【数据范围】

对于20%的数据,T=1

对于50%的数据,T<=5000

对于80%的数据,T<=50000

对于100%的数据,T<=500000;N<=5000000

A做法:直接打表。

代码实现:

 1 #include<cstdio>
 2 const int maxn=5000010;
 3 int t,n,s[maxn];
 4 int main(){
 5     for(int i=1;i<=maxn;i++)
 6     for(int j=i;j<=maxn;j+=i)
 7     s[j]+=i;
 8     scanf("%d",&t);
 9     while(t--){
10         scanf("%d",&n);
11         printf("%d\n",s[n]);
12     }
13     return 0;
14 }

B做法:枚举+读入优化+记忆化

代码实现(来着学长 神犇 ):

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 inline const int read(){
 4     register int x=0,f=1;
 5     register char ch=getchar();
 6     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 7     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
 8     return x*f;
 9 }
10 int T,v,f[100000010];
11 inline int go(){
12     int i,sum=0;
13     for(i=1;i*i<v;i++)
14         if(v%i==0) sum+=i+v/i;
15     if(i*i==v) sum+=i;
16     return sum;
17 }
18 int main(){
19     T=read();
20     while(T--){
21         v=read();
22         if(!f[v]) f[v]=go();
23         printf("%d\n",f[v]);
24     }
25     return 0;
26 }

题目来源:CODE[VS]

T2

题目背景

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。

自己水到了60分,然后看了学长的代码。

代码实现:

 1 #include<iostream>
 2 using namespace std;
 3 long long l,r,ans;
 4 int main(){
 5     cin>>l>>r;
 6     for(int i=1;i<=r;i++){
 7         ans+=r/i*i;
 8         ans-=(l-1)/i*i;
 9     }
10     cout<<ans<<endl;
11     return 0;
12 }
60分

后来的AC代码:

 1 #include<iostream>
 2 #define LL long long
 3 using namespace std;
 4 LL l,r,ans;
 5 LL evaluate(LL x){
 6     LL ret=0;
 7     for(LL i=1,j;i<=x;i=j+1){
 8         j=x/(x/i);
 9         ret+=x/i*(i+j)*(j-i+1)/2;
10     }
11     return ret;
12 }
13 int main(){
14     cin>>l>>r;
15     cout<<evaluate(r)-evaluate(l-1)<<endl;
16     return 0;
17 }

题目来源:洛谷

posted @ 2017-02-05 17:02  J_william  阅读(899)  评论(0编辑  收藏  举报