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

现在, 君希望你告诉他队伍整齐时能看到的学生人数。
链接🔗
Luogu P2158
题解🔗
学了一年 才会做这道题,退役退役QAQ
我们观察右下三角形的情况,答案只要再做一些简单的加减乘除就可以了。
从 能被看见的条件,就是在这两个点之间没有其他整点。可以发现,如果有不少于一个整点,那么必然这个区间会被整点若干等分(这若干个整点之间斜率相同),所以也就是满足 ,所以我们只需要求:
两个循环相同,直接用欧拉函数求解就好。
时间复杂度: 。
代码🔗
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| #include <cstdio>
using namespace std;
const int MAXN = 100000;
bool flag[MAXN];
int prime[MAXN],cnt;
int phi[MAXN];
void sieve(int n){
phi[1] = 1;flag[1] = 1;
for(int i = 2;i<=n;i++){
if(flag[i] == 0){
prime[++cnt] = i,phi[i] = i-1;
}
for(int j = 1;j<=cnt && i * prime[j] <= n;j++){
flag[i*prime[j]] = 1;
if(i % prime[j]){
phi[i * prime[j]] = phi[i] * (prime[j]-1);
}
else{
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
}
}
}
int main(){
int n;
scanf("%d",&n);
sieve(n);
long long ans = 0;
for(int i = 2;i<=n-1;i++){
ans += phi[i];
}
printf("%lld\n",n==1?0:ans*2+3);
return 0;
}
|