LightOJ1236->算术基本定理
2016-07-13 00:58
302 查看
算术基本定理的应用
题意:找出对于整数对(i,j),他们的lcm为n,这样的整数对有多少。
思路:比如24=2^3*3^1:
(1)如果一个数完整地包含了3^1但是没有完整地包含2^3(一个数x完整地包含某个质因数p及其出现的次数t,指x可以被p^t整除),比如3,6,12,那么另一个数必须完整地包含2^3,比如8,24。那么此时有六种组合(3,8),(3,24),(6,8),(6,24),(12,8),(12,24)
(2)若一个数完整地包含2^3但是没有完整地包含3^1,比如8,那么另一个数必须完整地包含3^1,比如3,6,12,24,此时有4个。
(3)若一个数完整地包含了2^3和3^1,比如24,那么另一个数有(3+1)*(1+1)种可能,即1,2,3,4,6,8,12,24。
(4)若一个数既没有完整的包含2^3也没有完整地包含3^1,比如1,2,4,那么另一个数必须为24,此时有3种。
到此为止,你发现除了(24,24)这种组合只在(3)中出现一次,其他情况均出现2次。若上面的总数为t,那么答案为(t+1)/2。
假设lcm(X,Y)=M,分别分解X,Y,M
X=x1^a1*x2^a2...
Y=x1^b1*x2^b2..
M=x1^c1*x2^c2..
因为是公倍数 所以质因数肯定要相同
那么max(a1,b1)=c1...max(a2,b2)=c2。
当b1=c1的时候a1的取法是(c1+1)种,a1=c1是b1取法也是(c1+1)种,但是有两个(c1,c1),所有对于每一个c1来说总的取法是(2*c1+1).
因为要求i<=j,所以最后结果去重一下,但是(n,n)只有一次,那么解就是(ans+1)/2。
题意:找出对于整数对(i,j),他们的lcm为n,这样的整数对有多少。
思路:比如24=2^3*3^1:
(1)如果一个数完整地包含了3^1但是没有完整地包含2^3(一个数x完整地包含某个质因数p及其出现的次数t,指x可以被p^t整除),比如3,6,12,那么另一个数必须完整地包含2^3,比如8,24。那么此时有六种组合(3,8),(3,24),(6,8),(6,24),(12,8),(12,24)
(2)若一个数完整地包含2^3但是没有完整地包含3^1,比如8,那么另一个数必须完整地包含3^1,比如3,6,12,24,此时有4个。
(3)若一个数完整地包含了2^3和3^1,比如24,那么另一个数有(3+1)*(1+1)种可能,即1,2,3,4,6,8,12,24。
(4)若一个数既没有完整的包含2^3也没有完整地包含3^1,比如1,2,4,那么另一个数必须为24,此时有3种。
到此为止,你发现除了(24,24)这种组合只在(3)中出现一次,其他情况均出现2次。若上面的总数为t,那么答案为(t+1)/2。
假设lcm(X,Y)=M,分别分解X,Y,M
X=x1^a1*x2^a2...
Y=x1^b1*x2^b2..
M=x1^c1*x2^c2..
因为是公倍数 所以质因数肯定要相同
那么max(a1,b1)=c1...max(a2,b2)=c2。
当b1=c1的时候a1的取法是(c1+1)种,a1=c1是b1取法也是(c1+1)种,但是有两个(c1,c1),所有对于每一个c1来说总的取法是(2*c1+1).
因为要求i<=j,所以最后结果去重一下,但是(n,n)只有一次,那么解就是(ans+1)/2。
#include <stdio.h> #include <iostream> #include <string.h> using namespace std ; #define MAX 10000100 bool visit[MAX] ; long long prime[MAX / 10] ; int tot = 0 ; void doprime()//素数筛 { for(long long i = 2 ; i < MAX ; i ++) { if(! visit[i]) { prime[tot ++] = i ; for(long long j = i * i ; j < MAX ; j += i) visit[j] = true ; } } } int p[1000] ;//素因子 int a[1000] ;//素因子个数 int cnt ; void sbreak(long long n)//素因子分解 { memset(p , 0 , sizeof(p)) ; memset(a , 0 , sizeof(a)) ; cnt = 0 ; for(int i = 0 ;prime[i] * prime[i] <= n ; i ++) { if(n % prime[i] == 0) { p[cnt] = prime[i] ; while(n % prime[i] == 0) { a[cnt] ++ ; n /= prime[i] ; } cnt ++ ; } } if(n != 1) { p[cnt] = n ; a[cnt ++ ] = 1 ; } } int main() { int T ; long long num ; doprime() ; cin >> T ; for(int cas = 1 ; cas <= T ; cas ++) { cin >> num ; sbreak(num) ; long long ans = 1 ; for(int i = 0 ; i < cnt ; i ++) ans = ans * (a[i] * 2 + 1) ; ans = (ans + 1) / 2 ; printf("Case %d: %lld\n",cas,ans); } return 0; }
相关文章推荐
- Android Studio .so 文件提交
- SRM549
- PHP中的错误处理、异常处理机制详解
- PHP中getenv()和$_SERVER的区别
- BZOJ 2002 [LCT]
- Qiuck_Cocos基础(一)
- 【ASP】Window2008站点安全设置,IIS7/IIS7.5中目录执行权限的设置方法
- SRM546
- 关于DIV多层嵌套的margin-top的BUG
- SRM545
- 为什么豌豆荚们没能成为伟大的公司?
- 图论一
- codeforce#630 B.Moore's Law
- 【张宴】PHP在金山游戏运营中的应用
- 教你从Core Data迁移到Realm
- SRM694
- SRM541
- linux下ioctl遇到的坑
- 一些PHP性能优化汇总
- tmux简要介绍