D. Madoka and the Best School in Russia
阿新 • • 發佈:2022-03-15
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; }