题目link
思路
问题可以理解为:
用 x 的beautiful因子,能否找到不少于2种的方案使得
x
=
a
1
∗
a
2
.
.
∗
a
n
x = a_1*a_2..*a_n
x=a1∗a2..∗an 成立,仅顺序不同为一种方案
类似于完全背包求方案数,用
x
x
x 的
b
e
a
u
t
i
f
u
l
beautiful
beautiful 因子为状态进行dp
这里考虑到
x
x
x 的范围到达
1
e
9
1e9
1e9,用
x
x
x的因子排序后的下标来映射因子
后面均用的是下标来进行转移;
如何转移呢?
用
x
x
x的
b
e
a
u
t
i
f
u
l
beautiful
beautiful因子
i
i
i作为状态,再枚举x的因子
j
j
j
当满足
(
x
/
i
%
j
=
=
0
)
(x/i \% j == 0)
(x/i%j==0) 时, 用
j
j
j 转移
i
∗
j
i*j
i∗j
这里
(
x
/
i
%
j
=
=
0
)
(x/i \% j == 0)
(x/i%j==0) 保证了
i
∗
j
i*j
i∗j 也为
x
x
x 的 因子
存在对应的映射值
详细转移见代码
code
学习于dls
/*
*@author:bzdhxs
*@date:2022/03/15
*@URL:
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<queue>
using namespace std;
template <typename T>
inline void read(T &s){s = 0;T w = 1, ch = getchar();while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^48); ch = getchar();} s *= w;}
template <typename T>
inline void write(T s){if (s < 0) putchar('-'), s = -s;if (s > 9) write(s / 10);putchar(s % 10 + '0');}
#define int long long
#define _orz ios::sync_with_stdio(false),cin.tie(0)
#define mem(str,num) memset(str,num,sizeof(str))
#define forr(i,a,b) for(int i = a; i <= b;i++)
#define forn(i,n) for(int i = 0; i < n; i++)
#define dbg() cout <<"0k!"<< endl;
typedef long long ll;
int pri[16] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};
const int inf = 0x3f3f3f3f;
const int INF = ~0ULL;
const int N = 1e6+10;
int x,d;
bool check(int k){
return (k % d == 0 && (k/d)%d != 0);
}
const int M = 100100;
int f[M],id[M],gid[M];
void sol(){
cin >> x >> d;
vector<int> fac;
for(int i = 1;i <= x/i;i++){
if(x%i == 0){
fac.push_back(i);
if(x != i*i) fac.push_back(x/i);
}
}
sort(fac.begin(),fac.end());
// 这里是用来映射因子的 考虑到有些值很大内存浪费严重
// 用两个数组来进行映射 因为最大为1e9 可以使 > 一定值(这里选le5)来分开存 详细见代码
for(int i = 0; i < fac.size();i++){
if(fac[i] <= M) id[fac[i]] = i;
else gid[x/fac[i]] = i;
}
forr(i,0,fac.size()) f[i] = 0;
f[0] = 1;
for(int i = 0; i < fac.size();i++)
if(check(fac[i])){
for(int j = 0; j < fac.size();j++){
if(x/fac[i] % fac[j] == 0){
int v = fac[i]*fac[j];
int d = (v <= M)?id[v]:gid[x/v];
f[d] = min(f[d]+f[j],2LL);
}
}
}
if(f[fac.size()-1] >= 2 ) puts("YES");
else puts("NO");
}
signed main()
{
int t;cin>>t;
while(t--) sol();
return 0;
}