Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19130 Accepted Submission(s): 5775
Problem Description
输入cas 再输入n 求n的所有因子之和
数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6.
Input
输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).
Output
对于每组测试数据,请输出一个代表输入数据N的所有因子的和
Sample Input
3 2 10 20
Sample Output
1 8 22
Author
Ignatius.L
Source
杭电ACM省赛集训队选拔赛之热身赛
首先 用暴力搞 毫无疑问超时
#include<stdio.h>
#include<string.h>
#include<math.h>
int vis[500000+5];
int c;
void get_prime()
{
int i,j,n,m;
c=0;
n=500000;
m=(int)sqrt(n+0.5);
memset(vis,0,sizeof(vis));
for(i=2;i<=m;i++)
if(!vis[i])
{
for(j=i*i;j<=n;j+=i)
vis[j]=1; //参观过的不是素数
}
}
int main()
{
int i,j,cas;
__int64 ans;
get_prime();
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&j);
ans=0;
if(!vis[j]) {printf("1\n");continue;}
for(i=1;i<j/2+1;i++)
if(j%i==0) ans+=i;
printf("%I64d\n",ans);
}
return 0;
}
百度了下
给我的启发: O(n)之内无法解决的问题 想办法 看看O(log(n)),O(sqrt(n))内能不能解决 能否进行转化
对于本题 是可以转化的
#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
int i,cas,n;
__int64 ans;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
ans=1;
// for(i=2;i<=(int)sqrt(n*1.0)+1;i++)//不能加1 否则WA 千万注意这里哦 精确度一定要搞清楚
//for(i=2;i<=sqrt(n*1.0);i++) //TLE
// for(i=2;i<=(int)sqrt(n*1.0);i++) //906ms险过
for(i=2;i*i<=n;i++)//250ms 轻松过 注意 以后尽量采取这种方式 另外sqrt 要int 强制转化才行
if(n%i==0)
{
ans+=i;
if(n/i!=i)
ans=ans+(n/i);
}
printf("%I64d\n",ans);
}
return 0;
}
再次百度下了其它方法
得到启发:
换位思考 题意是要我们求输入的数n的因子之和 一个劲超时
那么我们不如换换位 换换对象 看所有的因子各会出现在哪个数里面
#include<stdio.h>
__int64 a[500000+5];
int main()
{
int i,j,n,cas;
for(i=0;i<=500000;i++) a[i]=1;//1是所有数的因子
for(i=2;i<=250000;i++) //最大因子不会超过250000
{
for(j=i+i;j<=500000;j+=i)
a[j]+=i;
}
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
printf("%I64d\n",a[n]);
}
return 0;
}
Total Submission(s): 19130 Accepted Submission(s): 5775
Problem Description
输入cas 再输入n 求n的所有因子之和
数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6.
Input
输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).
Output
对于每组测试数据,请输出一个代表输入数据N的所有因子的和
Sample Input
3 2 10 20
Sample Output
1 8 22
Author
Ignatius.L
Source
杭电ACM省赛集训队选拔赛之热身赛
首先 用暴力搞 毫无疑问超时
#include<stdio.h>
#include<string.h>
#include<math.h>
int vis[500000+5];
int c;
void get_prime()
{
int i,j,n,m;
c=0;
n=500000;
m=(int)sqrt(n+0.5);
memset(vis,0,sizeof(vis));
for(i=2;i<=m;i++)
if(!vis[i])
{
for(j=i*i;j<=n;j+=i)
vis[j]=1; //参观过的不是素数
}
}
int main()
{
int i,j,cas;
__int64 ans;
get_prime();
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&j);
ans=0;
if(!vis[j]) {printf("1\n");continue;}
for(i=1;i<j/2+1;i++)
if(j%i==0) ans+=i;
printf("%I64d\n",ans);
}
return 0;
}
百度了下
给我的启发: O(n)之内无法解决的问题 想办法 看看O(log(n)),O(sqrt(n))内能不能解决 能否进行转化
对于本题 是可以转化的
#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
int i,cas,n;
__int64 ans;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
ans=1;
// for(i=2;i<=(int)sqrt(n*1.0)+1;i++)//不能加1 否则WA 千万注意这里哦 精确度一定要搞清楚
//for(i=2;i<=sqrt(n*1.0);i++) //TLE
// for(i=2;i<=(int)sqrt(n*1.0);i++) //906ms险过
for(i=2;i*i<=n;i++)//250ms 轻松过 注意 以后尽量采取这种方式 另外sqrt 要int 强制转化才行
if(n%i==0)
{
ans+=i;
if(n/i!=i)
ans=ans+(n/i);
}
printf("%I64d\n",ans);
}
return 0;
}
再次百度下了其它方法
得到启发:
换位思考 题意是要我们求输入的数n的因子之和 一个劲超时
那么我们不如换换位 换换对象 看所有的因子各会出现在哪个数里面
#include<stdio.h>
__int64 a[500000+5];
int main()
{
int i,j,n,cas;
for(i=0;i<=500000;i++) a[i]=1;//1是所有数的因子
for(i=2;i<=250000;i++) //最大因子不会超过250000
{
for(j=i+i;j<=500000;j+=i)
a[j]+=i;
}
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
printf("%I64d\n",a[n]);
}
return 0;
}