Good Numbers(HDU5447+唯一分解)
题目链接
题面
题意
首先定义对于\(k\)的好数\(u\):如果\(u\leq k\)且\(u\)的所有质因子与\(k\)的质因子一样则称\(u\)对于\(k\)是一个好数。
现给你两个数\(k1,k2(1\leq k1,k2\leq 10^{24})\),要你求\(k1,k2\)的好数个数,对于\(k1,k2\)有两者的最大质因子一定相同第二大质因子一定不同。
思路
我们知道对于小于等于\(10^{24}\)的数最多有三个大于\(10^6\)的质因子,因此对于数\(k1,k2\)我们可以先将其小于等于\(10^6\)的质因子全部分离出来,那么最后最多还剩三个质因子的指数相乘。
我们设\(p1,p2,p3\)为二者的最一、二、三大质因子。
如果最后剩余的\(k1,k2\)只剩\(p1\),那么就只能是\(p1\)的幂次,此时可以通过枚举求出\(p1\)的指数,因为大于\(1e6\)的数最多\(3\)次就大于\(10^{24}\)了。
如果最后剩余的\(k1,k2\)剩\(p1,p2\)的幂次相乘,那么\(gcd(k1,k2)\)一定是\(p1\)的幂次,因为二者的\(p2\)一定不同嘛~这样我们可以通过两次枚举得到其指数。
如果最后剩余的\(k1,k2\)剩\(p1,p2,p3\)的幂次相乘,那么\(p1,p2,p3\)的指数一定都是\(1\)次。
因为好数的要求是需要质因子与\(k\)相同,所以每个质因子的次数至少为\(1\),所以如果\(k=p_1^{c_1}p_2^{c_2}\dots\),那么答案就是\(\prod\limits_{i=1}^{n}c_i\)。
代码实现如下
import java.util.*;
import java.math.*;
public class Main {
static int cnt = 0;
static Boolean v[] = new Boolean[1000007];
static int p[] = new int[1000007];
public static void init() {
for(int i = 0; i <= 1000000; ++i) v[i] = false;
for(int i = 2; i <= 1000000; ++i) {
if(!v[i]) p[cnt++] = i;
for(int j = 0; j < cnt && i * p[j] <= 1000000; ++j) {
v[i*p[j]] = true;
if(i % p[j] == 0) break;
}
}
}
public static int check(BigInteger k) {
if (k.equals(BigInteger.ONE)) return 1;
BigInteger a = BigInteger.valueOf((long)Math.sqrt(k.doubleValue()));
if (k.equals(a.multiply(a))) return 2;
a = a.add(BigInteger.ONE);
if (k.equals(a.multiply(a))) return 2;
BigInteger b = BigInteger.valueOf((long)Math.pow(k.doubleValue(), 1.0/3));
if (k.equals(b.multiply(b.multiply(b)))) return 3;
b = b.add(BigInteger.ONE);
if (k.equals(b.multiply(b.multiply(b)))) return 3;
return 1;
}
public static void main(String[] args) {
init();
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
BigInteger k[] = new BigInteger[5];
while(t-- != 0) {
for(int i = 0; i < 2; ++i) k[i] = sc.nextBigInteger();
long ans[] = new long[5];
for(int i = 0; i < 2; ++i) {
ans[i] = 1L;
for(int j = 0; j < cnt; ++j) {
if(k[i].mod(BigInteger.valueOf(p[j])) == BigInteger.ZERO) {
long num = 0;
while(k[i].mod(BigInteger.valueOf(p[j])) == BigInteger.ZERO) {
++num;
k[i] = k[i].divide(BigInteger.valueOf(p[j]));
}
ans[i] *= num;
}
}
}
k[2] = k[0].gcd(k[1]);
if(k[2].compareTo(BigInteger.valueOf(1000000)) > 0) {
int x = check(k[2]);
BigInteger g;
if(x == 1) g = k[2];
else if(x == 2) {
BigInteger tmp = BigInteger.valueOf((long)Math.sqrt(k[2].doubleValue()));
if(k[2].equals(tmp.multiply(tmp))) g = tmp;
else g = tmp.add(BigInteger.ONE);
} else {
BigInteger tmp = BigInteger.valueOf((long)Math.pow(k[2].doubleValue(), 1.0/3));
if(k[2].equals(tmp.multiply(tmp).multiply(tmp))) g = tmp;
else g = tmp.add(BigInteger.ONE);
}
for(int i = 0; i < 2; ++i) {
long num = 0;
while(k[i].mod(g) == BigInteger.ZERO) {
++num;
k[i] = k[i].divide(g);
}
ans[i] *= num;
if(k[i].compareTo(BigInteger.valueOf(1000000)) > 0) {
ans[i] *= check(k[i]);
}
}
}
System.out.println(ans[0] + " " + ans[1]);
}
sc.close();
}
}
对象用\(=\)进行比较是否相等是看地址。

Good Numbers(HDU5447+唯一分解)的更多相关文章
- K. Random Numbers(Gym 101466K + 线段树 + dfs序 + 快速幂 + 唯一分解)
题目链接:http://codeforces.com/gym/101466/problem/K 题目: 题意: 给你一棵有n个节点的树,根节点始终为0,有两种操作: 1.RAND:查询以u为根节点的子 ...
- HDU5447 Good Numbers
http://acm.hdu.edu.cn/showproblem.php?pid=5447 网上好像只找到java的题解,写完就发一下c++代码咯,顺便纪念一下+存个int128板子 做法可以看tj ...
- SPOJ:Divisors of factorial (hard) (唯一分解&分块优化)
Factorial numbers are getting big very soon, you'll have to compute the number of divisors of such h ...
- Min25 筛与 Powerful Numbers
Min25 筛与 Powerful Numbers Min25 筛 大喊一声 Min25 NB!!! 这是一个非常神奇的东西,用于求更加普遍的积性函数的前缀和. 比如我们要求 \(\sum_{i=1} ...
- Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range
在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...
- POJ 2739. Sum of Consecutive Prime Numbers
Sum of Consecutive Prime Numbers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 20050 ...
- [LeetCode] Add Two Numbers II 两个数字相加之二
You are given two linked lists representing two non-negative numbers. The most significant digit com ...
- [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...
- [LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...
随机推荐
- 24 AdminLTE 基础入门
1.AdminLTE介绍 AdminLTE是一款建立在bootstrap和jquery之上的开源的模板主题工具,它提供了一系列响应的.可重复使用的组件,并内置了多个模板页面:同时自适应多种屏幕分辨率, ...
- SQL Server中的GAM页和SGAM页
简介 我们已经知道SQL Server IO最小的单位是页,连续的8个页是一个区.SQL Server需要一种方式来知道其所管辖的数据库中的空间使用情况,这就是GAM页和SGAM页. Global A ...
- Mac Mini(late 2014) 添加NVMe固态组Fusion Drive
我买的是Mac Mini(late 2014)中配,内置5400转1T机械硬盘,该配置即使到了2019年安装macOS Mojave系统依旧是够用的,但硬盘严重拖累了运行的速度.之前考虑到更换内置sa ...
- js拼接url以及为html某标签属性赋值
记录 js拼接url 比如有些时候我们需要为某按钮实现跳转,可以利用下面的方式做到: function ReturnIndex() { var rex = RegExp("tools&quo ...
- 复制Linux虚拟机(VMware vSphere Client 工具)
1.VMware vSphere Client 工具 登录,如下图 IP.用户名/密码均是物理机,登录完成界面: 2.选择一个复制的原虚拟机 A,点击左上角[文件]——导出——导出O ...
- centos 7 搭建 k8s
环境 Centos 7.2 master 192.168.121.101node-1 192.168.121.134node-2 192.168.121.135 Kubernetes集群组件:– et ...
- 【简解】SP7556 Stock Charts
题目大意 给出一个折线图,有N条线段,你想要把这些线段分成几个集合,使得每个集合中任意两条线段不相交. 求最少集合数. 分析 喵帕斯:以下提及的所有折线均指横坐标在\([1,k]\)里的折线段. 思考 ...
- POI2015 WYC
也许更好的阅读体验 \(\mathcal{Description}\) 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长 ...
- SQL Server 2012启动时提示:无效的许可证数据,需要重新安装
因为手咸,觉得电脑没有VS 2010版本的软件,就把Microsoft Visual C++ 2010某个组件给卸载了. 然后打开Sql Server 2012,就开始报错. 重装之后,也还是报错,将 ...
- A Deep Dive Into Draggable and DragTarget in Flutter
https://medium.com/flutter-community/a-deep-dive-into-draggable-and-dragtarget-in-flutter-487919f6f1 ...