[SDOI2008] 仪仗队【题解】

题目描述#

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

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

思路#

题目给出一个 n×n 的点阵,对于这个点阵,我们从左下角到右上角画一条斜线,分离左上部分和右下部分。

然后我们可以发现这个点阵是根据这条对角线对称的。

对于这条对角线,我们从右上角开始,对其经过的点依次进行标号。

最后发现有 n 个点。

第 1 个和第 n 个处于最角上(其中一个还是自己),不可能看到。

对于对角线上剩下的点依次进行分析。

我们已知这条线上的点是看不到的(坐标点右上角那一个点除外,单独分析)。

· · · · · 1
· · · · 2 ·
· · · 3 · ·
· · 4 · · ·
· 5 · · · ·
6 · · · · ·

我们可以发现,其中一部分与该编号的点是可以看到的点。
因此,最终是求 2 到 n-1 互质的个数。

Code#

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define MAXN 40500 

using namespace std;

int prime[MAXN],cnt,phi[MAXN];
bool isprime[MAXN];

void eular()// 线性筛求欧拉函数  
{
	for(int i = 1;i <= MAXN; i++)
		isprime[i] = 1;
	isprime[1] = 0;
	phi[1] = 1;
	for(int i = 2;i <= MAXN; i++)
	{
		if( isprime[i] )
		{
			prime[++cnt] = i;
			phi[i] = i - 1;
		}
		
		for(int j = 1;j <= cnt and i*prime[j] <= MAXN; j++)
		{
			isprime[i*prime[j]] = 0;
			if( i%prime[j] != 0 )
				phi[i*prime[j]] = phi[i] * phi[prime[j]];
			else
			{
				phi[i*prime[j]] = phi[i] * prime[j];
				break;
			}
		}
	}
}

int main()
{
	int n;
	cin >> n;
	eular(); 
	int sum = 0;
	for(int i = 2;i < n; i++)
		sum += phi[i];
	 
	cout << sum*2 + 3;
	return 0;
}

作者:白简

出处:https://www.cnblogs.com/baijian0212/p/yizhangdui.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   -白简-  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu