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 ...
随机推荐
- [数据结构 - 第3章] 线性表之双向链表(C语言实现)
一.什么是双向链表? 双向链表(double linked list)是在单链表的每个结点中,再设置一个指向其前驱结点的指针域.所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前 ...
- (CSDN迁移) JAVA多线程实现-可控最大并发数线程池(newFixedThreadPool)
上篇文章中介绍了单线程化线程池newSingleThreadExecutor,可控最大并发数线程池(newFixedThreadPool)与其最大的区别是可以通知执行多个线程,可以简单的将newSin ...
- 局域网-断网&劫持(kali)
1.查看局域网中的主机 fping –asg 192.168.1.0/24 2.断网 arpspoof -i wlan0 -t 192.168.100 192.168.1.1 (arpspoof - ...
- Java 中成员变量被局部变量所隐藏
Java 中局部变量与成员变量同名时,局部变量会隐藏成员变量.如果我们想访问成员变量,可以使用 this 关键字. class Test { private int value = 10; void ...
- Navicat 创建oracle表空间、新建用户、授权
1.利用数据库管理员账号:SYSTEM,再配合数据库管理口令,连接Oracle数据库. 登录界面: 2.创建表空间文件 进入如下界面 进入如下界面 弹出如下界面,输入表空间名称 最终结果: 2 .新 ...
- 用easyui实现查询条件的后端传递并自动刷新表格的两种方法
用easyui实现查询条件的后端传递并自动刷新表格的两种方法 搜索框如下: 通过datagrid的load方法直接传递参数并自动刷新表格 通过ajax的post函数传递参数并通过loadData方法将 ...
- Golang修改json文件的两种方法
第三方包 go get -u github.com/tidwall/sjson bytes, _ := ioutil.ReadFile(jsonFile) value1, _ := sjson.Set ...
- 忘记token怎么加入k8s集群
一.概述 新版本的k8s,初始化生成的token,只有24小时.超过时间,就得需要重新生成token,为了避免这种情况,直接生成永久的token 二.操作步骤 1.生成一条永久有效的token kub ...
- kafka学习笔记(一)——概述
1.kafka是什么? 官方说明是: Kafka是一个分布式的基于发布/订阅模式的消息队列,主要应用于大数据实时处理领域. 提到了两个概念: 发布/订阅模式 消息队列 下边来理解一下这两个名词. 2. ...
- yii框架里DetailView视图和GridView的区别
1,首先从语义上分析 DetailView是数据视图,用于显示一条记录的数据,相当于网页中的详情页 GridView是网格视图,用于显示数据表里的所有记录,相当于网页里的列表页 2.用法上的区别 首先 ...