[CF1878F] Vasilije Loves Number Theory 的题解

题目大意

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

  1. 给定 x,令 nnx。同时询问是否存在一个正整数 a 满足 gcd(a,n)=1d(na)=n
  2. n 还原为最初的值。

数据保证任何时刻,d(n)109

思路

因为题目其实并没有要求输出 a 具体的值,所以我们并不需要真正的将 a 求解出来,而只需要判断存在性就可以了。

因为 n 可能会很多次被乘以 x,所以我们就可以储存 n 的所有的质因子。

假设 n 在质因数分解之后有 k 个质因子,而且第 i 个质因子出现了 xi 次,那么总共的因子数量就是 i=1kxi+1

对于这个性质,我们可以感性的理解一下:对于每一个质因子,我们可以选 num[0,xi] 个,即有 xi+1 种可能性。通过乘法原理就可以得到因子数量为 i=1kxi+1

如果满足 d(n)|n 就一定可以找到满足条件的 a 反之就不可能,理由如下:

对于 a 取任何数一定满足 d(an)|d(n)

因为 d(n)=i=1kxi+1d(an)=i=1kxi+yi+1,其中 yiia 的质因子的个数。

对于 d(an) 一定可以找到一个 a 使 d(n)q=d(n),此时的 a=sq1,其中 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 @   未抑郁的刘大狗  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示