hihoCoder1284机会渺茫(唯一分解定理 + 约分)

题目链接

#1284 : 机会渺茫

时间限制:5000ms

单点时限:1000ms

内存限制:256MB

描述

小Hi最近在追求一名学数学的女生小Z。小Z其实是想拒绝他的,但是找不到好的说辞,于是提出了这样的要求:对于给定的两个正整数N和M,小Hi随机选取一个N的约数N‘,小Z随机选取一个M的约数M‘,如果N‘和M‘相等,她就答应小Hi。

小Z让小Hi去编写这个随机程序,到时候她review过没有问题了就可以抽签了。但是小Hi写着写着,却越来越觉得机会渺茫。那么问题来了,小Hi能够追到小Z的几率是多少呢?

输入

每个输入文件仅包含单组测试数据。

每组测试数据的第一行为两个正整数N和M,意义如前文所述。

对于40%的数据,满足1<=N,M<=10^6

对于100%的数据,满足1<=N,M<=10^12

输出

对于每组测试数据,输出两个互质的正整数A和B(以A分之B表示小Hi能够追到小Z的几率)。

样例输入
3 2
样例输出
4 1

分析:对 n 和 m 分解,得到n和m的每一个素数的指数en[],em[],然后取公约数,即取每个指数小的那个得到新的 et[], sum(et[]) / sum(en[]) * sum(em[])即所求,就是在en里面找一个,在em里面找一个,1/(sum[en] * sum[em]),一共有sum[et]个题目等级为2,然后我却WA了好几次,RE了好几次 =_=...

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 typedef long long LL;
 6 const int Max = 10000000 + 5; //开到6次RE
 7 bool flag[Max + 5];
 8 int prime[Max + 5], tot;
 9 int en[Max + 5], em[Max + 5], et[Max + 5];
10 void get_prime()
11 {
12     memset(flag, false, sizeof(flag));
13     tot = 0;
14     for (int i = 2; i <= Max;i ++)
15     {
16         if (!flag[i])
17         {
18             prime[++tot] = i;
19             for (int j = i; j <= Max / i; j++)
20                 flag[i * j] = true;
21         }
22     }
23 }
24 void get_fact(LL n, int * temp)
25 {
26     memset(temp, 0, sizeof(temp));
27     for (int i = 1; i <= tot; i++)
28     {
29         if (prime[i] > n)
30             break;
31         if (n % prime[i] == 0)
32         {
33             while (n % prime[i] == 0)
34             {
35                 n = n / prime[i];
36                 temp[prime[i]]++;
37             }
38         }
39     }
40     if (n > 1)
41         temp[n]++;
42 }
43 LL get_sum(int temp[])
44 {
45     LL sum = 1;
46     for (int i = 1; i <= tot; i++)
47     {
48         if (temp[prime[i]])
49             sum *= (temp[prime[i]] + 1);
50     }
51     return sum;
52 }
53 void solve()
54 {
55     memset(et, 0, sizeof(et));
56     for (int i = 1; i <= tot; i++)
57     {
58         if (en[prime[i]] && em[prime[i]])
59         {
60             int minn = min (en[prime[i]], em[prime[i]]);  //取最小的指数
61             et[prime[i]] += minn;
62         }
63     }
64 }
65 LL get_gcd(LL a, LL b)
66 {
67     if (b == 0)
68         return a;
69     return get_gcd(b, a % b);
70 }
71 int main()
72 {
73     get_prime();
74     LL n, m;
75     scanf("%lld%lld", &n, &m);
76     get_fact(n, en);
77     get_fact(m, em);
78     solve();
79     LL numn = get_sum(en);
80     LL numm = get_sum(em);
81     LL numf = get_sum(et);
82
83    // 最后结果就是 numf / (numn * numm)
84    所以先对numf 和 numn约分,
85   然后把约分后的numf与numm约分,最后numn * numm
86     LL x1 = numf;
87     LL t1 = get_gcd(numn, numf);
88     x1 = x1 / t1;
89     numn = numn / t1;
90
91     LL t2 = get_gcd(numm, x1);
92     x1 = x1 / t2;
93     numm = numm / t2;
94     numn = numn * numm;
95
96     printf("%lld %lld\n", numn, x1);
97     return 0;
98 }

时间: 2024-10-21 07:48:35

hihoCoder1284机会渺茫(唯一分解定理 + 约分)的相关文章

hihocoder-1284 机会渺茫(水题)

机会渺茫 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最近在追求一名学数学的女生小Z.小Z其实是想拒绝他的,但是找不到好的说辞,于是提出了这样的要求:对于给定的两个正整数N和M,小Hi随机选取一个N的约数N',小Z随机选取一个M的约数M',如果N'和M'相等,她就答应小Hi. 小Z让小Hi去编写这个随机程序,到时候她review过没有问题了就可以抽签了.但是小Hi写着写着,却越来越觉得机会渺茫.那么问题来了,小Hi能够追到小Z的几率是多少呢? 输入 每个输入

[ACM] HDU 3398 String (从坐标0,0走到m,n且不能与y=x-1相交的方法数,整数唯一分解定理)

String Problem Description Recently, lxhgww received a task : to generate strings contain '0's and '1's only, in which '0' appears exactly m times, '1' appears exactly n times. Also, any prefix string of it must satisfy the situation that the number

UVa 10375 Choose and divide (唯一分解定理)

题目 题目大意 已知\(C(m, n) = m! / (n!(m - n)!)\), 输入整数\(p\), \(q\), \(r\), \(s\)(\(p ≥ q\), \(r ≥ s\), \(p\), \(q\), \(r\), \(s ≤ 10000\)), 计算\(C(p, q) / C(r, s)\).输出保证不超过\(10^8\), 保留\(5\)位小数 题解 这道题还是挺水吧... 首先如果直接算出\(C(p, q)\)和\(C(r, s)\)是肯定不可能的, C++存不下这么大的

有趣的数列 唯一分解定理+卡特兰数

问题: 我们称一个长度为\(2n\)的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从\(1\)到\(2n\)共\(2n\)个整数的一个排列{\(Ai\)}: (2)所有的奇数项满足\(A1<A3<-<A2n-1\),所有的偶数项满足\(A2<A4<-<A2n\): (3)任意相邻的两项\(A2i-1\)与\(A2i(1≤i≤n)\)满足奇数项小于偶数项,即:\(A2i-1<A2i\). 现在的任务是:对于给定的\(n\),请求出有多少个不同的长度为\

HDU 1452 Happy 2004(唯一分解定理)

题目链接:传送门 题意: 求2004^x的所有约数的和. 分析: 由唯一分解定理可知 x=p1^a1*p2^a2*...*pn^an 那么其约数和 sum = (p1^0+p1^1^-+p1^a1)*-* (pn^0+pn^1^-+pn ) 代码如下: #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; const

NOIP2009Hankson 的趣味题[唯一分解定理|暴力]

题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson.现 在,刚刚放学回家的 Hankson 正在思考一个有趣的问题. 今天在课堂上,老师讲解了如何求两个正整数 c1 和 c2 的最大公约数和最小公倍数.现 在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公 倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数 a0,a1,b0,b1,设某未知正整 数 x 满足: 1. x 和 a0 的最大公约

欧几里德算法和唯一分解定理

刘汝佳<入门经典>上提供了一道经典的题目: 除法表达式,在NYOJ上可以找到原题,题号1013 描述 给出一个这样的除法表达式:X1/X2/X3/···/Xk,其中Xi是正整数.除法表达式应当按照从左到右的顺序求和,例如表达式1/2/1/2值为1/4.但是可以在表达式中嵌入括号以改变计算顺序,例如表达式(1/2)/(1/2)的值为1. 输入 首先输入一个N,表示有N组测试数据, 每组数据输入占一行,为一个除法 表 达式,输入保证合法. 使表达式的值为整数.k<=10000,Xi<=

Coderforce-574C Bear and Poker(素数唯一分解定理)

题目大意:给出n个数,问能不能通过让所有的数都乘以2的任意幂或乘以3的任意幂,使这n个数全都相等. 题目分析:最终n个数都是相等的,假设那个数为x,根据素数唯一分解定理,x能分解成m*2p3q.所以,只需将所有的a[i]一直除以2并且一直除以3,最终只需判断这n个数是否全部相等即可. 代码如下: # include<iostream> # include<cstdio> # include<cmath> # include<string> # include

唯一分解定理(算术基本定理)及应用

算术基本定理:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积 N = p1^a1 * p2^a2 * p3^a3 * ... * pn^an (其中p1.p2.... pn为N的因子,a1.a2.... .an分别为因子的指数) 这样的分解称为 N 的标准分解式 应用: (1)一个大于1的正整数N,如果它的标准分解式为: N = p1^a1 * p2^a2 * p3^a3 * ... * pn^an (2)N的因子个数     M(N)= (1 + a1)*(1