UVa294 Divisors

在一段区间[l,r]内,找出因数最多的数的个数以及其因数个数。

 

用唯一分解定理将一个数分解成质因数的乘积,例如 2^p1*3^p2*5^p3*7^p4*....  从这些质因数中任选出一些数相乘,都可以组成原数的因数,总方案数为(p1+1)*(p2+1)*(p3+1)*...   注:+1是因为可以不选,全部不选的话得到数字1,也是原数的因数。

 

r<=1000000000,对其开根号得到31622,也就是说不会存在两个以上大于31622的质因数。素数筛算出1~3w+的质数。接下来用唯一分解定理算出区间内每个数的因数个数←暴力扫描即可。(0 ≤ L − R ≤ 10000)10000*30000次计算(实际到不了这么多),并不会炸。

 

 

 1 /*by SilverN*/
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #define LL long long
 8 using namespace std;
 9 const int mxn=48000;
10 int pri[mxn],cnt=0;
11 bool vis[mxn];
12 int num[mxn];
13 void Pri(){//素数筛
14     cnt=0;int i,j;
15     for(i=2;i<mxn;i++){
16         if(!vis[i])pri[++cnt]=i;
17         for(j=1;j<=cnt && i*pri[j]<mxn;j++){
18             vis[i*pri[j]]=1;
19             if(i%pri[j]==0)break;
20         }
21     }
22     return;
23 }
24 int dvi(int a){//计算因数个数
25     int res=1;
26     int i,j;
27     int time=0;
28     for(i=1;i<=cnt && a>1;i++){
29         time=0;
30         while(a%pri[i]==0){
31             time++;
32             a/=pri[i];
33         }
34         res*=(time+1);
35     }
36     if(a>1)res*=2;
37     return res;
38 }
39 int l,r;
40 int main(){
41     Pri();
42     int i,j;
43     int T;
44     scanf("%d",&T);
45     while(T--){
46         scanf("%d%d",&l,&r);
47         int pos=l;
48         int mx=dvi(l);int tmp;
49         for(i=l+1;i<=r;i++){
50             tmp=dvi(i);
51             if(tmp>mx){
52                 mx=tmp;
53                 pos=i;
54             }
55         }
56         printf("Between %d and %d, %d has a maximum of %d divisors.\n",l,r,pos,mx);
57     }
58     return 0;
59 }

 

posted @ 2016-09-22 22:59  SilverNebula  阅读(280)  评论(0编辑  收藏  举报
AmazingCounters.com