Acwing 5286 翻倍

链接 : 

https://www.acwing.com/problem/content/5289/

思路 :

  • 根据算术基本定理 : 一个数一定能够能被分成若干个质数的乘积,所以只需要考虑k取质数的情况了;

  • 假设在操作过程中选取的质数为 : p1,p2,p3...pm,分别选取的个数为a1,a2,a3,...am,那么总的操作次数为 : a1+a2+a3+...am

  • 假设一次操作中x选k=x,那么a和b一起会乘上x^(3t),(x选了t次)

  • 那么a*b就可以表示为 :

  • Acwing 5286 翻倍_第1张图片

  • 对每个选取的质数进行分析 : p1选了a1次,对于a : p1这个质因子出现的次数x必须要在(a1<=x<=2*a1)这个范围内,那么对于b : p1这个质因子满足(a1 <= y <= 2 * a1) , 且满足x + y = 3 * a1;

  • Acwing 5286 翻倍_第2张图片

    如果ab中质因子p1的出现次数不为3的倍数,那么直接就false了,反之有a1 = (x + y) / 3 , 并且还要满足下a1<=x(等价于) && a1 <= y , 然后依次类推;

  • 对ab分解质因数:

    Acwing 5286 翻倍_第3张图片

  • 那么等价于 :

    Acwing 5286 翻倍_第4张图片

  • 即 :

  • Acwing 5286 翻倍_第5张图片

  • 还要清楚的一点是 ; 若b|a,且c|a,那么bc|a,那么如果t=ab开3次方根,且t为整数,那么要满足题目条件的话,只需要满足t|a且t|b即可;

Acwing 5286 翻倍_第6张图片

 

代码 : 

#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
inline void solve(){
    int a,b;cin>>a>>b;
    int t = round(pow((LL)a*b,1.0/3)); // round()  : 四舍五入 , 除去x.99999...的影响
    if(t*(LL)t*t == (LL)a*b && a%t==0 && b%t==0) puts("Yes");
    else puts("No");
} 
int main()
{
    int n ; cin >> n;
    while(n--) solve();
    return 0;
}

你可能感兴趣的:(算法学习,acwing,算法,c++)