洛谷 P 2158 仪仗队(欧拉筛法解法)

题目描述

作为体育委员,C 君负责这次运动会仪仗队的训练。仪仗队是由学生组成的 N×N 的方阵,为了保证队伍在行进中整齐划一,C 君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。

现在,C 君希望你告诉他队伍整齐时能看到的学生人数。

输入格式

一行,一个正整数 NN。

输出格式

输出一行一个数,即 C 君应看到的学生人数。

输入输出样例

输入 #1复制

4

输出 #1复制

9

 解题思路:

即对任意整点 (x,y) ,点 (λx,λy),(λ>1) 是看不到的

我们可以显然发现:gcd(λx,λy)=λgcd(x,        y)>λ⋅1=λ>1

也就是说,对于一个点 (x,y) ,当gcd(x,y)=1 时这个点看不到

而对于任意满足 gcd(x,y)=1 的点 (x,y) ,若它会被遮挡,则必定有整点 ,(mx​,my​),(m>1) 存在

根据 gcd(x,y)=1 ,我们能发现这样的点不存在

所以我们得出结论:一个点 (x,y) 能被看到,当且仅当 gcd(x,y)=1

	#include<bits/stdc++.h>
	using namespace std;
	const int N = 50000;
	int vis[N];
	int prime[N];
	int phi[N];
	int sum[N];
	void get_phi() {
		phi[1] = 1;
		int cnt = 0;
		for (int i = 2; i < N; i++) {
			if (!vis[i]) {
				vis[i] = i;
				prime[cnt++] = i;
				phi[i] = i - 1;
			}
			for (int j = 0; j < cnt; j++) {
				if (i * prime[j] > N) break;
				vis[i * prime[j]] = prime[j];
				int m = i * prime[j];
				if (i % prime[j] == 0) { // m = prime[i] * i * ````
					phi[m] = phi[i] * prime[j]; 
					break;
				}
				phi[m] = phi[i] * phi[prime[j]];
			}
		}
	}
	int main() {
		get_phi();
		sum[1] = 1;
		for (int i = 2; i <= N; i++)
			sum[i] = sum[i - 1] + phi[i];
		int n;
		cin >> n;
		if (n == 1) cout << "0" << endl;
		else {
			printf("%d\n", 2 * sum[n - 1] + 1);
		}
		return 0;
	}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值