D. Madoka and the Best School in Russia

D. Madoka and the Best School in Russia
好数的定义是:是d的倍数。
美丽的数的定义是:是好数且不能表示成两个好数的乘积。
问:给定一个好数x和d,问x是否有超过两种方式,能够表示成若干个的美丽的数的乘积(两个以上)。只回答是与否即可。
根据美丽的数的定义:我们可以假定a是一个美丽的数,则有a=md,且m不是d的倍数。即a是d的倍数,但不是\(d^2\)的倍数。
将x分解成若干个美丽的数的乘积,可以认为\(x=x_1,x_2,x_3,x_4...\),其中\(x_1,x_2,x_3...\)都是d的倍数,但不是\(d^2\)的倍数。
既然这样,我们可以用DP解决。设f[n]表示当前数除以某些合法的数后到达n的方案数.最后判断f[1]的方案数与2的关系即可。注意枚举的时候我们要单调的枚举因子.
这个时候就可以跑一下合法的数量的因子的个数,反正很少就对了。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int T,x,d,b[100000];
map<pair<int,int>,int>mp;
inline bool check(int x)
{
    if(x%d==0&&(x/d)%d!=0) return 1;
    return 0; 
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&x,&d);
        int num=0;
        for(int i=1;i<=sqrt(x);++i)
        {
            if(x%i==0)
            {
                if(check(i)) b[++num]=i;
                if(i*i!=x&&check(x/i)) b[++num]=x/i;
            }
        }
        sort(b+1,b+num+1);
        mp.clear();
        mp[{x,num}]=1;
        int ans=0;
        while(mp.size())
        {
            auto now=*prev(mp.end());
            int v=now.first.first,id=now.first.second,cos=now.second;
            if(v==1) ans+=cos;
            for(int i=id;i>=1;--i)
            {
                if(v%b[i]==0)
                {
                    mp[{v/b[i],i}]+=cos;
                }
            }
            mp.erase(prev(mp.end()));
        }
        if(ans>1) puts("YES");
        else puts("NO");
    }
    return 0;
}
posted @ 2022-03-15 17:16  逆天峰  阅读(172)  评论(0编辑  收藏  举报
作者:逆天峰
出处:https://www.cnblogs.com/gcfer//