Codeforces Round #777 D
D. Madoka and the Best School in Russia
我们可以知道x是又其众多因子构成的 所以我们可以先暴力枚举他的因子取出来即可 题解说的不会超过700个 很神秘
然后就是一个因子选和不选 选几次 是不是很像一个背包问题 那我们就可以用dp来解决(先枚举每一个点 在枚举每一种方案)
但是这里我们还要维护合法性 以及顺序问题 状态表示就是dp[i]为从x点到达i点的方案数
我们类似于迭代的做法 只需要每次除的数都必须大于上一次除的数即可 那我们还需要维护一个维度即可
由于x的数据范围较大 我们使用map 来减少空间 并且跳过不需要更新的点
然后就再对于每一个下标做暴力除并且判断其合法性即可
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 1000000007;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int x,d;
bool check(int n){
if(n%d==0&&(n%(d*d)))return 1;
else return 0;
}
void solve() {
cin>>x>>d;
vector<int>del;
map<pair<int,int>,int>dp;
dp[{x,1}]=1;
for(int i=1;i<=x;i++){
if(x%i==0){
if(check(i))del.push_back(i);
if(i*i!=x&&check(x/i))del.push_back(x/i);
}
}
int ans=0;
while(dp.size()){
auto now=*prev(dp.end());
int n=now.first.first,k=now.first.second,cot=now.second;
if(n==1)ans+=cot;
for(auto i:del){
if(n%i==0&&i>=k)dp[{n/i,i}]+=cot;
}
dp.erase(prev(dp.end()));
}
if(ans>=2)YES
else NO
}
signed main(){
fast
int T;cin>>T;
while(T--) {
solve();
}
return ~~(0^_^0);
}