洛谷 P2350 [HAOI2012]外星人(素因子分解,欧拉函数)

该博客介绍了如何利用欧拉函数和素因子分解解决一道关于寻找最小x使得φx(N)=1的问题。博客内容涉及算法竞赛题目[HAOI2012]外星人,讲解了输入输出格式,并提供了样例。博主分析了素数表的构建、欧拉函数的性质,特别是对于奇素数如何通过素因子分解产生2的个数,以及如何计算最终结果。解决方案包括计算素因子2的数量并累加,特别指出没有素因子2的情况需额外处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[HAOI2012]外星人

题目描述

艾莉欧在她的被子上发现了一个数字 N N N,她觉得只要找出最小的 x x x 使得, φ x ( N ) = 1 \varphi^x(N) = 1 φx(N)=1。根据这个 x x x 她就能找到曾经绑架她的外星人的线索了。当然,她是不会去算,请你帮助她算出最小的 x x x

输入格式

第一行一个正整数 t e s t \mathrm{test} test,接下来 t e s t \mathrm{test} test 组数据每组数据第一行一个正整数 m m m,接下来 m m m 行每行两个正整数 p i , q i p_i, q_i pi,qi

其中 ∏ i = 1 m p i q i \displaystyle \prod_{i = 1}^{m} p_i^{q_i} i=1mpiqi N N N 的标准分解形式。

∏ \prod 为连乘

φ x ( N ) \varphi^x(N) φx(N) 表示嵌套 x x x 次,不是幂

输出格式

输出 t e s t \mathrm{test} test 行,每行一个整数,表示答案。

样例 #1

样例输入 #1

1
2
2 2
3 1

样例输出 #1

3

提示

30 % 30\% 30% 的数据, N ≤ 1 0 6 N \le 10^6 N106

60 % 60\% 60% 的数据, x ≤ 100 x \le 100 x100

100 % 100\% 100% 的数据, t e s t ≤ 50 \mathrm{test} \le 50 test50 1 ≤ p i ≤ 10 5 1 \le p_i \le {10}^5 1pi105 1 ≤ q i ≤ 10 9 1 \le q_i \le {10}^9 1qi109 m ≤ 2000 m \le 2000 m2000

φ \varphi φ 为欧拉函数, φ ( n ) \varphi(n) φ(n) 即小于等于 n n n 的数中与 n n n 互质的数的个数。

提示: φ ( ∏ i = 1 m p i q i ) = ∏ i = 1 m ( p i − 1 ) ∗ p i q i − 1 \varphi(\prod_{i=1}^mp_i^{q_i})=\prod_{i=1}^m(p_i-1)*p_i^{q_i-1} φ(i=1mpiqi)=i=1m(pi1)piqi1

1、 素数的大小 <= 10^5, 直接用线性筛法打素数表
2、 题目给出的提示, 假如 p, q 都是素数, phi(p^n * q^m) = (p - 1)*p^(n - 1) * (q - 1) *q^(m - 1)
如果 p 是奇素数(p != 2), p - 1 必然含有 素因子2。 每一个奇数素数 减1, 再做素因子分解,
也必然含有 素因子2。 所以这道题跟素因子 2 有关。
3、 观察 n = p1^a1 * p2^a2 * … * pk^ak,
现在单独拿出一个素因子 pj 来考虑, pj - 1 也做素因子分解, 分解出好多素因子(假如有一个是 k),
k - 1 也要做素因子分解, …, 一直进行下去,都会分解出 素因子 2。
现在考虑的是,一个奇素数,做这样的操作,一共能搞出多少个2?
factor_2[p] 表示 素数减1, p - 1, 一直分解,最后能得到多少个2
显然 p - 1 = x * y (x, y 都是素数) ,那么
factor_2[p] = factor_2[x] + factor_2[y]
5、 每做一次欧拉函数的运算,素因子2就减少一个。
4、数组int factor_2[MaxN] 求出来后,题目就好解决了。 累加结果就行。
注意,如果一开始没有素因子2, 最后的结果要加1

#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
const int MaxN = 100010;
const int MaxM = 2010;
int prime[MaxN], m;
int v[MaxN];	// v[i] 表示 i 包含的最小的素因子
bool vis[MaxN];

int factor_2[MaxN];	// factor_2[13] 表示 13 - 1 = 12 = 2^2 * 3  , 3 - 1 = 2^1  , 素因子减 1, 然后再因式分解,
					// 最后能得到 3 个 素因子2

int T, M;
int p[MaxM], q[MaxM];


void factor_2_init()
{
	factor_2[2] = 1;
	for (int i = 2; i <= m; ++i)
	{
		int p = prime[i] - 1;
		int cnt = 0, tmp = 0;
		for (int j = 1; prime[j] <= sqrt(p); ++j)
		{
			if (p % prime[j] == 0)
			{
				tmp = 0;
				while (p % prime[j] == 0)
				{
					++tmp;
					p /= prime[j];
				}
				cnt += factor_2[prime[j]] * tmp;
			}
		}
		tmp = 0;
		if (p > 1)	// 如果此时p 大于1, 说明p还是个素数
		{
			cnt += factor_2[p];
		}
		factor_2[prime[i]] = cnt;
	}
}


void prime_init()
{
	int n = MaxN - 10;
	m = 0;	//素数的个数
	for (int i = 2; i <= n; ++i)
	{
		if (v[i] == 0)
		{
			v[i] = i; prime[++m] = i;
		}
		for (int j = 1; j <= m; ++j)
		{
			if (prime[j] > v[i] || prime[j] > n / i)
				break;
			v[i * prime[j]] = prime[j];
		}
	}
}


int main()
{
	prime_init();
	factor_2_init();
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d", &M);
		long long ans = 0;
		for (int i = 1; i <= M; ++i)
		{
			scanf("%d%d", &p[i], &q[i]);
			ans += factor_2[p[i]] * q[i];
		}
		if (p[1] != 2)
			ans++;
		printf("%lld\n", ans);
	}
	return 0;
}


/*
1
2
2 2
3 1
*/

/*
3
*/

智能网联汽车的安全员高级考试涉及多个方面的专业知识,包括但不限于自动驾驶技术原理、车辆传感器融合、网络安全防护以及法律法规等内容。以下是针对该主题的一些核心知识解析: ### 关于智能网联车安全员高级考试的核心内容 #### 1. 自动驾驶分级标准 国际自动机工程师学会(SAE International)定义了六个级别的自动驾驶等级,从L0到L5[^1]。其中,L3及以上级别需要安全员具备更高的应急处理能力。 #### 2. 车辆感知系统的组成与功能 智能网联车通常配备多种传感器,如激光雷达、毫米波雷达、摄像头和超声波传感器等。这些设备协同工作以实现环境感知、障碍物检测等功能[^2]。 #### 3. 数据通信与网络安全 智能网联车依赖V2X(Vehicle-to-Everything)技术进行数据交换,在此过程中需防范潜在的网络攻击风险,例如中间人攻击或恶意软件入侵[^3]。 #### 4. 法律法规要求 不同国家和地区对于无人驾驶测试及运营有着严格的规定,考生应熟悉当地交通法典中有关自动化驾驶部分的具体条款[^4]。 ```python # 示例代码:模拟简单决策逻辑 def decide_action(sensor_data): if sensor_data['obstacle'] and not sensor_data['emergency']: return 'slow_down' elif sensor_data['pedestrian_crossing']: return 'stop_and_yield' else: return 'continue_driving' example_input = {'obstacle': True, 'emergency': False, 'pedestrian_crossing': False} action = decide_action(example_input) print(f"Action to take: {action}") ``` 需要注意的是,“同学”作为特定平台上的学习资源名称,并不提供官方认证的标准答案集;建议通过正规渠道获取教材并参加培训课程来准备此类资格认证考试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值