专栏文章

CF1878F Vasilije Loves Number Theory 题解

CF1878F题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minjeozu
此快照首次捕获于
2025/12/02 03:23
3 个月前
此快照最后确认于
2025/12/02 03:23
3 个月前
查看原文
结论就是当 nn 能被 d(n)d(n) 整除时为 Yes,其他题解都有详细讲解,不再赘述,这里主要讲一下实现。
这里的方法简单粗暴,对于 xx,对它进行质因数分解,乘的 nn 也分解并且和 xx 的结果相加(开一个 map 即可)若直接计算 d(n)d(n) 是不可取的,所以我们可以采取逐步取模的策略,让结果不太大。
如何求 d(n)d(n) 大家应该都清楚就是用约数个数定理加上快速幂就可以快速求出了。
代码:
CPP
#include <bits/stdc++.h>

#define int long long 

using namespace std;

int ksm(int a, int b, int mod)
{
	int ans = 1;
	while (b)
	{
		if (b & 1) ans = (ans * a) % mod;
		a = (a * a) % mod;
		b >>= 1;
	}
	return (int)ans;
}

signed main()
{
	int T;
	cin >> T;
	while (T -- )
	{
		int n, q;
		scanf("%lld%lld", &n, &q);
		map<int, int> now, org;
		int x = n;
		int lim = (int)floor(sqrt(x));
		for (int i = 2; i <= lim; i ++ )
		{
			while (x % i == 0)
			{
				now[i] ++ ;
				x /= i;
			}
		}
		if (x > 1) now[x] ++ ;
		org = now;
		while (q -- )
		{
			int op;
			scanf("%lld", &op);
			if (op == 2) now = org; 
			else
			{
				int t;
				scanf("%lld", &t);
				int tmp = t;
				int lim2 = (int)floor(sqrt(tmp));
				for (int i = 2; i <= lim2; i ++ )
				{
					while (tmp % i == 0)
					{
						now[i] ++ ;
						tmp /= i;
					}
				}
				if (tmp > 1) now[tmp]++;
				int d = 1;
				map<int, int> :: iterator it = now.begin();
				while (it != now.end())
				{
					int e = it->second;
					d *= (e + 1);
					it ++ ;
				}
				int res = 1;
				it = now.begin();
				while (it != now.end())
				{
					int p = it->first, q = it->second;
					int pw = ksm(p, q, d);
					res = (res * pw) % d;
					it ++ ;
				}
				if (res % d == 0) puts("YES");
				else puts("NO");
			}
		}
		puts("");
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...