[CF1878F] Vasilije Loves Number Theory 的题解
题目大意
令 \(d(x)\) 表示 \(x\) 的正因子数量,给定 \(n,q\)。现有两种操作:
- 给定 \(x\),令 \(n\gets n\cdot x\)。同时询问是否存在一个正整数 \(a\) 满足 \(\gcd(a,n)=1\) 且 \(d(n\cdot a)=n\)。
- 将 \(n\) 还原为最初的值。
数据保证任何时刻,\(d(n)\leq 10^9\)。
思路
因为题目其实并没有要求输出 \(a\) 具体的值,所以我们并不需要真正的将 \(a\) 求解出来,而只需要判断存在性就可以了。
因为 \(n\) 可能会很多次被乘以 \(x\),所以我们就可以储存 \(n\) 的所有的质因子。
假设 \(n\) 在质因数分解之后有 \(k\) 个质因子,而且第 \(i\) 个质因子出现了 \(x_i\) 次,那么总共的因子数量就是 \(\prod_{i=1}^{k} x_i+1\)。
对于这个性质,我们可以感性的理解一下:对于每一个质因子,我们可以选 \(num\in[0,x_i]\) 个,即有 \(x_i+1\) 种可能性。通过乘法原理就可以得到因子数量为 \(\prod_{i=1}^{k} x_i+1\)。
如果满足 \(d(n)|n\) 就一定可以找到满足条件的 \(a\) 反之就不可能,理由如下:
对于 \(a\) 取任何数一定满足 \(d(a\cdot n)|d(n)\)。
因为 \(d(n)=\prod_{i=1}^{k} x_i+1\),\(d(a\cdot n)=\prod_{i=1}^{k} x_i+y_i+1\),其中 \(y_i\) 以 \(i\) 为 \(a\) 的质因子的个数。
对于 \(d(a\cdot n)\) 一定可以找到一个 \(a\) 使 \(d(n)\cdot q=d(n)\),此时的 \(a=s^{q-1}\),其中 \(s\) 是一个极大质数。
因为题目要求 \(\gcd(a,n)=1\),所以只要满足 \(s\) 并非 \(n\) 的质因子即可。
AC Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q;
map<int,int> mp,mp1;
void solve() {
cin>>n>>q;
for(int i=2;i*i<=n;i++) {
while(n%i==0){
mp[i]++;
n/=i;
}
}
if(n>1){
mp[n]++;
}
mp1=mp;
for (int i=1,op,x;i<=q;i++){
std::cin>>op;
if(op==2){
mp=mp1;
continue;
}
cin>>x;
for(int j=2;j*j<=x;j++) while(x%j==0) mp[j]++,x/=j;
if(x>1) mp[x]++;
int cnt=1;
for(auto i:mp) cnt*=(i.second+1);
bool flag=1;
for(int j=2;j*j<=cnt;j++){
int sum=0;
while(cnt%j==0) sum++,cnt/=j;
if(sum>mp[j]){
flag=0;
break;
}
}
if(cnt>1&&!mp[cnt]||!flag) cout<<"NO\n";
else cout<<"YES\n";
}
mp.clear();
cout<<'\n';
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin>>t;
while(t--) solve();
return 0;
}