首页 > 其他 > 详细

唯一分解定理

时间:2020-04-15 13:49:30      阅读:57      评论:0      收藏:0      [点我收藏+]

唯一分解定理又称为算数基本定理,基本内容是:

每个大于1的自然数,要么本身就是质数,要么可以写为2个或以上的质数的积,而且这些质因子按大小排列之后,写法仅有一种方式。

用另一种方法表示就是:

对于任何一个大于1的正整数,都存在一个标准的分解式:  N=p1^a1 * p2^a2*···*pn^an;(其中一系列an为指数,pn为质数)

此定理表明:任何一个大于 1 的正整数都可以表示为素数的积。

有这样几个式子:

设F(n)代表n的正因子的数量,则F(n)=(a1+1)*(a2+1)*(a3+1)*······*(an+1);

设G(n)代表n的正因子的和,则G(n)=(1+p1^2+p1^3+...+p1^a1)*(1+p2^2+p2^3+...p2^a2)*....*(1+pn^1+pn^2+...+pn^an);

 

获得一个数正因子数量的代码:

primel [ ]是素数表

 1 ll getfac(ll x)
 2 {
 3     ll ans=1;
 4     for(int i=1;i<=cnt&&primel[i]<=x;i++)
 5     {
 6         ll sum=0;//当前质因数的幂指数 
 7         while(x%primel[i]==0)//当是这个数的因子时 
 8         {
 9             sum++;
10             x/=primel[i];
11         }
12         ans*=(sum+1);//应用定理的结论 
13     }
14     if(x>1)//当搜索不到的时候,如果这个数最后大于一,那么这个最后结果肯定是素数,并且指数是1 
15     ans*=2;
16     return ans;
17 }

 

来看一个应用此定理的例题:

链接:Light OJ 1341 Aladdin and the Flying Carpet

此题的题意就是,给定一个矩形(非正方形)的面积 a,求可以分解的长*宽有多少组,且任意一条边不能小于b,不能重复(4*3和3*4重复)。

即求一个数可以分解为多少个正因数相乘,想到唯一分解定理,用它把所有可能的因子找出后,再除以2,在把小于b的因子暴力去除。

看代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=1e6+20;
 7 int primel[maxn];
 8 bool isp[maxn];
 9 int cnt;
10 void makel()//欧拉筛打印素数表 
11 {
12     cnt=0;
13     memset(isp,true,sizeof(isp));
14     for(int i=2;i<maxn;i++)
15     {
16         if(isp[i])
17         primel[++cnt]=i;
18         for(int j=1;j<=cnt;j++)
19         {
20             if(i*primel[j]>maxn)
21             break;
22             isp[i*primel[j]]=false;
23             if(i%primel[j]==0)
24             break;
25         }
26     }
27 }
28 ll getfac(ll x)//唯一分解定理 
29 {
30     ll ans=1;
31     for(int i=1;i<=cnt&&primel[i]<=x;i++)
32     {
33         ll sum=0; 
34         while(x%primel[i]==0) 
35         {
36             sum++;
37             x/=primel[i];
38         }
39         ans*=(sum+1);
40     }
41     if(x>1) 
42     ans*=2;
43     return ans;
44 }
45 int main()
46 {
47     int t;
48     int cas=0;
49     ll a,b;
50     cin>>t;
51     makel();
52     while(t--)
53     {
54         scanf("%lld%lld",&a,&b);
55         if(a<b*b)//不可能分解为比b大的数相乘 
56         {
57         printf("Case %d: 0\n",++cas);
58         continue;
59         }
60         ll count=getfac(a)/2;//不能重复 
61         for(int i=1;i<b;i++)//去除小于b的因子 
62         {
63             if(a%i==0)
64             count--;
65         }
66         printf("Case %d: %lld\n",++cas,count);
67     }
68     return 0;
69 }

 

唯一分解定理

原文:https://www.cnblogs.com/theshorekind/p/12704405.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!