[CF1878F] Vasilije Loves Number Theory 的题解

题目大意

\(d(x)\) 表示 \(x\) 的正因子数量,给定 \(n,q\)。现有两种操作:

  1. 给定 \(x\),令 \(n\gets n\cdot x\)。同时询问是否存在一个正整数 \(a\) 满足 \(\gcd(a,n)=1\)\(d(n\cdot a)=n\)
  2. \(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;
}
posted @ 2024-07-14 13:44  未抑郁的刘大狗  阅读(3)  评论(0编辑  收藏  举报