Codeforces 833A The Meaningless Game - 数论 - 牛顿迭代法 - 二分法

Slastyona and her loyal dog Pushok are playing a meaningless game that is indeed very interesting.

The game consists of multiple rounds. Its rules are very simple: in each round, a natural number k is chosen. Then, the one who says (or barks) it faster than the other wins the round. After that, the winner‘s score is multiplied by k2, and the loser‘s score is multiplied by k. In the beginning of the game, both Slastyona and Pushok have scores equal to one.

Unfortunately, Slastyona had lost her notepad where the history of all n games was recorded. She managed to recall the final results for each games, though, but all of her memories of them are vague. Help Slastyona verify their correctness, or, to put it another way, for each given pair of scores determine whether it was possible for a game to finish with such result or not.

Input

In the first string, the number of games n (1 ≤ n ≤ 350000) is given.

Each game is represented by a pair of scores ab (1 ≤ a, b ≤ 109) – the results of Slastyona and Pushok, correspondingly.

Output

For each pair of scores, answer "Yes" if it‘s possible for a game to finish with given score, and "No" otherwise.

You can output each letter in arbitrary case (upper or lower).

Example

input

62 475 458 816 16247 9941000000000 1000000

output

YesYesYesNoNoYes

Note

First game might have been consisted of one round, in which the number 2 would have been chosen and Pushok would have won.

The second game needs exactly two rounds to finish with such result: in the first one, Slastyona would have said the number 5, and in the second one, Pushok would have barked the number 3.



  题目大意 (题目太简洁不需要大意,看原文吧)

  对于每组询问等于求这么一个方程组的一组解,判断解是否是整数:

  首先可以得到,设它为x,那么有

  显然解是整数解的条件是x为整数且a,b均能被x整除。前半个条件又等价于ab为完全立方数。

  这个判断嘛。。牛顿迭代去开立方,二分法,HashMap都可以。

  为了装逼先写了个牛顿迭代,然而大概是我的牛顿迭代常数逆天,所以跑得比较慢。

Code

 1 /**
 2  * Codeforces
 3  * Problem#833A
 4  * Accepted
 5  * Time: 468ms
 6  * Memory: 2100k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 typedef bool boolean;
11 #define double long double
12
13 const double eps = 1e-1;
14 double sqrt3(double x) {
15     double r = x;
16     double f = 1, k;
17     do {
18         f = r * r * r - x;
19         k = 3 * r * r;
20         r -= f / k;
21     } while (f > eps);
22     return r;
23 }
24
25 int a, b;
26 long long P;
27 inline void init() {
28     scanf("%d%d", &a, &b);
29     P = a * 1LL * b;
30 }
31
32 inline boolean solve() {
33     long long x = sqrt3(P);
34     if(x * x * x != P)    return false;
35     return !(a % x || b % x);
36 }
37
38 int T;
39 int main() {
40     scanf("%d", &T);
41     while(T--) {
42         init();
43         puts(solve() ? ("Yes") : ("No"));
44     }
45     return 0;
46 }

The Meaningless Game(Newton‘s Methon)

  然后写了一个二分法,快了将近一倍。

Code

 1 /**
 2  * Codeforces
 3  * Problem#833A
 4  * Accepted
 5  * Time: 218ms
 6  * Memory: 2052k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 typedef bool boolean;
11 #define LL long long
12
13 int sqrt3(LL x) {
14     int l = 1, r = 1e6;
15     while(l <= r) {
16         LL mid = (l + r) >> 1;
17         if(mid * mid * mid <= x)    l = mid + 1;
18         else r = mid - 1;
19     }
20     return l - 1;
21 }
22
23 int a, b;
24 long long P;
25 inline void init() {
26     scanf("%d%d", &a, &b);
27     P = a * 1LL * b;
28 }
29
30 inline boolean solve() {
31     long long x = sqrt3(P);
32     if(x * x * x != P)    return false;
33     return !(a % x || b % x);
34 }
35
36 int T;
37 int main() {
38     scanf("%d", &T);
39     while(T--) {
40         init();
41         puts(solve() ? ("Yes") : ("No"));
42     }
43     return 0;
44 }

The Meaningless Game(Binary Search)

  最后写了一个可以用Hash的二分法(Excuse me?新型long long开方向下取整?)

Code

 1 /**
 2  * Codeforces
 3  * Problem#833A
 4  * Accepted
 5  * Time: 233ms
 6  * Memory: 9900k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 typedef bool boolean;
11 #define LL long long
12
13 const int limit = 1e6;
14 LL arr3[limit + 1];
15 inline void rinit() {
16     for(int i = 1; i <= limit; i++)
17         arr3[i] = i * 1LL * i * i;
18 }
19
20 int a, b;
21 long long P;
22 inline void init() {
23     scanf("%d%d", &a, &b);
24     P = a * 1LL * b;
25 }
26
27 inline boolean solve() {
28     int x = lower_bound(arr3 + 1, arr3 + limit + 1, P) - arr3;
29     if(arr3[x] != P)    return false;
30     return !(a % x || b % x);
31 }
32
33 int T;
34 int main() {
35     rinit();
36     scanf("%d", &T);
37     while(T--) {
38         init();
39         puts(solve() ? ("Yes") : ("No"));
40     }
41     return 0;
42 }
时间: 2024-08-04 00:38:31

Codeforces 833A The Meaningless Game - 数论 - 牛顿迭代法 - 二分法的相关文章

Codeforces 833A The Meaningless Game

http://codeforces.com/problemset/problem/833/A a*b开三方,检查是否是整数且a,b能整除它就好. #include<cstdio> #include<cmath> using namespace std; #define ll long long int T; ll a,b; int main(){ scanf("%d",&T); while(T--){ scanf("%lld%lld"

牛顿迭代法求解平方根

牛顿迭代法求解平方根 2015-05-16 10:30 2492人阅读 评论(1) 收藏 举报 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 一个实例 迭代简介 牛顿迭代法 牛顿迭代法简介 简单推导 泰勒公式推导 延伸与应用 一个实例 //java实现的sqrt类和方法 public class sqrt { public static double sqrt(double n) { if (n<0) return Double.NaN; double err = 1e

经典算法:牛顿迭代法求平方根

//牛顿迭代法求平方根 1 double mysqrt(double num) 2 { 3 double x = num/2; 4 double y = 0; 5 do{ 6 x = x/2+num/(2*x); 7 y = x*x-num; 8 if(y<0) y = -y; 9 } while(y>0.0001); 10 return x; 11 } 12 int main(int argc, char* argv[]) 13 { 14 printf("%.3f",my

51nod 1166 大数开平方(高精度+牛顿迭代法)

分析:直接用二分还是会T,用更快的牛顿迭代法.把问题转化为求x^2-n=0的根,假设解为x0,当前解为x且x^2-n>0,在(x,x^2-n)处作切线,与x轴交点横坐标为新的x,然后迭代即可,比二分法快,但是貌似只能用在凹函数或凸函数上.. java水高精度真是666... 1 import java.io.*; 2 import java.util.*; 3 import java.math.BigInteger; 4 public class Main { 5 public static v

牛顿迭代法(Newton&#39;s Method)

牛顿迭代法(Newton's Method) 简介 牛顿迭代法(简称牛顿法)由英国著名的数学家牛顿爵士最早提出.但是,这一方法在牛顿生前并未公开发表. 牛顿法的作用是使用迭代的方法来求解函数方程的根.简单地说,牛顿法就是不断求取切线的过程. 对于形如f(x)=0的方程,首先任意估算一个解x0,再把该估计值代入原方程中.由于一般不会正好选择到正确的解,所以有f(x)=a.这时计算函数在x0处的斜率,和这条斜率与x轴的交点x1. f(x)=0中精确解的意义是,当取得解的时候,函数值为零(即f(x)的

C语言实现牛顿迭代法解方程

利用迭代算法解决问题,需要做好以下三个方面的工作: 一.确定迭代变量 在可以用迭代算法解决的问题中,我们可以确定至少存在一个可直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量. 二.建立迭代关系式 所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系).迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成. 三.对迭代过程进行控制 在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题.不能让迭代过程无休止地执行下去.迭代过程的控制通常可分为两种情况

sqrt (x) 牛顿迭代法

参考: 0开方 是 0 1的开方式 1 2的开方式 1.4 3.的开方=(1.4+3/1.4)/2 牛顿迭代法:学习自 http://blog.csdn.net/youwuwei2012/article/details/34075241 public class Solution { public int sqrt(int x) { if(x==0)return 0; double pre=0; double cur=1; while(Math.abs(cur-pre)>0.000001) {

Atitit 迭代法&#160;&#160;“二分法”和“牛顿迭代法&#160;attilax总结

Atitit 迭代法  "二分法"和"牛顿迭代法 attilax总结 1.1. ."二分法"和"牛顿迭代法"属于近似迭代法1 1.2. 直接法(或者称为一次解法),即一次性的快速解决问题,1 1.3. 最常见的迭代法是"二分法 牛顿法.还包括以下算法1 1.4.  二分法(dichotomie)1 1.5. 牛顿迭代法(Newton's method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method

c语言:用牛顿迭代法求方程在1.5附近的根:2x^3-4x^2+3x-6=0.

用牛顿迭代法求方程在1.5附近的根:2x^3-4x^2+3x-6=0. 解:牛顿迭代法又叫牛顿切线法.设f =2x^3-4x^2+3x-6,f1为方程的导数,则f1 = 6x^2 - 8x+3,且f1=(f(x0)-0)/(x0-x1),推导得:x1 = x0 - f / f1 程序: #include<stdio.h> #include<math.h> int main() { double x0,x1,f,f1; x1 = 1.5; do { x0 = x1; f = 2*x0