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;
}