CodeForces

来源:互联网 发布:淘宝ipad版怎么找相似 编辑:程序博客网 时间:2024/06/09 05:07

题目来源:http://codeforces.com/problemset/problem/834/C


C. The Meaningless Game
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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.



题目大意:给你两个数a,b,验证是否可以化为a=s^2*p ; b=s*p^2。


思路:由于每组有350000数据,在验证时需要尽可能得高效。


假如数据a和b满足题意,那么假定a=s^2*p ; b=s*p^2,则a*b=s^3*p^3,即,不妨令m=s*p,那么a,b均应能够整除m,也就是(a/m)*(b/m)=m成立。


如果a,b不满足题意,则不妨令a=s^2*p*c ; b=s*p^2,a*b=s^3*p^3*c。如果a*b不能够开立方,那么一定不合题意。


现在讨论此时a*b的立方根存在的情况。即c存在立方根。那么a可表示为a=s^2*p*x^3,b为b=s*p^2。


a*b=s^3*p^3*x^3。a*b的立方根为s*p*x,令m=s*p*x。显然a可以整除m。b/m=(s*p^2)/(s*p*x)=p/x。


如果p/x不是整数,那么等式(a/m)*(b/m)=m不成立。


那么当p/x是整数时呢?我困扰了好久不敢断定通过等式(a/m)*(b/m)=m来验证是否是正确的,事实上,如果p/x是整数,则a和b一定满足题意,因此验证结果也是正确的。现给出证明:


因为p/x是整数,不妨令p/x=t,那么p=t*x。因此

a=s^2*p*x^3=s^2*t*x^4=(s*x^2)^2*t ; 

b=s*p^2=s*t^2*x^2=(s*x^2)*t^2 ;


满足a=s^2*p ; b=s*p^2的形式,故此时的a和b满足题意。


现在考虑另一种可能的情况,如果a=s^2*p*c1 ; b=s*p^2*c2。那么假如c1*c2的立方根存在(若不存在则不合题意),只可能是c1*c2=x*x^2(此时a,b显然满足题意)或c1*c2=x1^3*x2^3。那么当c1*c2=x1^3*x2^3时,a和b/c2=s*p^2可转化为a=s^2*p ; b=s*p^2的形式(上面已证),b再乘以x2^3又转化为上面的形式,故此时的a,b仍是满足题意的。


在交代码时,TLE了几次,需要进行一些优化,比如在输出时用gets而不是cout。提前构造好立方值的表省去每次验证时的计算。


找立方根时用二分查找,可用STL里的lower_bound函数。


代码:


#include <cstdio>#include <cstring>#include <iostream>#include <cstdlib>#include <algorithm>using namespace std;long long t[1000003];int main(){ios::sync_with_stdio(false);cin.tie(0);for(int i=1;i<=1000000;i++)t[i]=(long long)i*i*i;int _;cin>>_;long long a,b;while(_--){cin>>a>>b;int p=lower_bound(t+1,t+1+1000000,a*b)-t;if(p>1000000&&t[p]!=a*b){puts("No");continue;}a/=p;b/=p;if(a*b==p)puts("Yes");  else puts("No");}return 0;}

原创粉丝点击