您的位置:首页 > 其它

仪仗队[SDOI2008][bzoj2190]

2016-06-04 17:32 316 查看

题目描述 Description

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



输入描述 Input Description

共一个数 N。

输出描述 Output Description

共一个数,即 C 君应看到的学生人数。

样例输入 Sample Input

4

样例输出 Sample Output

9

数据范围及提示 Data Size & Hint

对于 100% 的数据, 1≤N≤40000

分析

对于第 (x,y) 号同学 C ,当且仅当 gcd(x,y)=1 或 x=0,y=1 或 x=1,y=0 。除开x=0,y=1 和 x=1,y=0 的特殊情况,就是要求 x 与 y 互质,又 x,y 的位置可以互换,再加上 (1,1) 互换之后任不变位置的特殊情况,所以 ans=3+∑i=2n−1φ(i)

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int prime[40020];
bool no_prime[40020];
int tx[40020];
int oula[40020];
int sum[40020];
int n;
int tot;

void get_prime(int);

int main(){

scanf("%d",&n);

get_prime(n-1);

printf("%d",sum[n-1]);

return 0;

}

void get_prime(int x){

sum[1] = 3;
oula[1] = 1;
for(int i=2,j,t;i<=x;++i){
if(!no_prime[i]){
prime[++tot] = i;
tx[i] = i;
}
j=1,t=i*prime[1];
while(j<=tot && t<=x){
no_prime[t] = true;
tx[t] = tx[i];
if(i%prime[j] == 0)
break;
t = i*prime[++j];
}
if(!no_prime[i])
oula[i] = i-1;
else{
if(i/tx[i]%tx[i] == 0)
oula[i] = oula[i/tx[i]]*tx[i];
else
oula[i] = oula[i/tx[i]]*(tx[i]-1);
}
sum[i] = sum[i-1]+(oula[i]<<1);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学