Codeforces Round #777 D. Madoka and the Best School in Russia

本文探讨了如何根据d和a的性质(如质数、合数和指数关系)来确定一个含有多个d的数x能否分解成两个漂亮数的乘积。关键发现包括d等于a的平方时的特殊情况和d为合数时的分解限制。通过实例和代码证明,得出了关于质数和合数d条件下x分解形式的结论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

x里如果只有一个d,x只能被表示为d*a(d*a是一个漂亮数),找不到第二种符合条件的形式了。

x里如果有2个d,尝试把x表示成 d(一个漂亮数)*  d*a(另一个漂亮数),是否还有第二种取决于a是合数还是质数,如果a是质数就没有了。若是合数肯定有,因为你可以把a分成两个数b,c ,然后把x表示为d*b(一个漂亮数) * d*c (另一个漂亮数)

x里如果有3个d,尝试把x表示成 d * d * (d*a) 同上面的情况,a如果是合数则肯定有。不同于上面的是,a如果是质数是有可能有另一种形式的,我们可以尝试把(d*a)分成两个b,c然后把x表示为d*b(一个漂亮数) * d*c (另一个漂亮数)

如果d也是质数,很显然是分不出来能使得d*b 是一个漂亮数 d*c 是另一个漂亮数的b,c

现在的问题是,如果d是合数,能不能分出符合条件的两个b,c,通过 128 4 这个样例 我们可以察觉到好像当d==a*a的时候是不能分出来的,现在就缺严谨的证明了

当d==a*a,d*a也就是 a^3,要分成两个都拿不出 a^2 的数是不可能的,

一共两种分法 a a^2,1 a^3 这两种分法都至少有一个数拿得出a^2 .

已经证明了d==a*a是不行的,那剩下的情况是不是一定可以呢?

如果d只有a这一个质因子,d==a^n(n>=3)d*a就可以分成 a^2 和 a^(n-1) 这两个数都拿不出d

现在看d存在非a的质因子的情况,为了叙述的方便,我们把d中非a的质因子记为e

d*a就可以分解成  e 和 d*a/e 

e肯定拿不出d咯,d*a/e 要想拿出来d,只能让a==e了,这与我们的前提条件:e是d中非a的质因子矛盾,所以是拿不出d的

至此,我们严谨的证明出了:当a是质数,d是合数,只有在d==a*a时,不能把d*a分成两个我们想要的b,c.

再看看当x里有4个d,同样的,如果a,d都是质数肯定不行。a是合数肯定行,那a是质数,d是合数的情况呢?

上面已经证明过了:当a是质数,d是合数,只有在d==a*a时,不能把d*a分成两个我们想要的b,c. 所以只要d!=a*a,我们就可以找到第二种形式

但你要知道,这里有4个d了,这就意味着我们可以把d*a分成三个拿不出d的数

再来看看d==a*a,d*a就是a^3 我们可以把它分成3个a 就可以把 x表示为 d*a  *  d*a  *  d*a  这3个漂亮数相乘

所以,在x里有4个d时,a是质数,d是合数的情况下一定可以找到第二种形式

虽然我写的十分冗长,但还是很严谨的,重要的还是自己思考

AC代码

#include<iostream>
#include<string>
#include<queue>
#include<algorithm>
#include<set>
#include<cmath>
#include<cstring>
using namespace std;
typedef unsigned long long ll;
const int mod=12345;
const int maxn=1e6+10;
bool is_prime(int x)
{
    for(int i=2;i<=x/i;i++)
    {
        if(x%i==0) return false;
    }
    return true;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int x,d;
        cin>>x>>d;
        int cnt=0;
        while(x%d==0){
            cnt++;
            x/=d;
        }
        if(cnt==1) cout<<"NO"<<endl;
        else if(cnt==2)
        {
            if(!is_prime(x)) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
        else
        {
            if(is_prime(x)&&(is_prime(d)||(cnt==3&&d==x*x))) cout<<"NO"<<endl;
            else 
            {
                cout<<"YES"<<endl;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值