仪仗队[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); } }