BZOJ2190 SDOI2008 仪仗队
flag:数论,欧拉函数。
http://www.lydsy.com/JudgeOnline/problem.php?id=2190
PS:我们发现当x1=k*x
y1=k*y时
此刻正能看见一个
于是又GCD(X1,Y1)>=2是只能看到一个==》等价于
GCD(X1,Y1)=1;
我们想到:
{盗图}
这个公式,因为其实点在(1,1) 所以需要n-1,n-1;
然后这个公式等于
的两倍-1
因为(1,1)算了两次
于是有了:筛法求phi;
再求和;
code:
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <cstring> 7 #define ll long long 8 #define ull unsigned long long 9 10 using namespace std; 11 12 bool f[40001]; 13 ull p[40001]; 14 ull ans[40001]; 15 16 int main() 17 { 18 int n,tot=0; 19 cin >>n; 20 if (n<=1){ 21 cout <<0 <<endl; 22 return 0; 23 } 24 25 memset(f,false,sizeof(f)); 26 f[1]=true; 27 for (int i=2;i<=n;i++){ 28 if (!f[i]){ 29 p[++tot]=i; 30 ans[i]=i-1; 31 } 32 33 for (int j=1;j<=tot&&i*p[j]<=n;j++) 34 { 35 f[i*p[j]]=1; 36 if (i%p[j]==0) 37 { 38 ans[i*p[j]]=ans[i]*p[j]; 39 break; 40 } 41 else ans[i*p[j]]=ans[i]*(p[j]-1); 42 } 43 44 for (int j=1;(j<=tot)&&(i*p[j]<=n);j++){ 45 f[i*p[j]]=true; 46 if (i%p[j]==0){ 47 ans[i*p[j]]=ans[i]*p[j]; 48 break; 49 } 50 else{ 51 ans[i*p[j]]=ans[i]*(p[j]-1); 52 } 53 } 54 } 55 57 long long pr=2; 58 for (int i=2;i<=n-1;i++) pr+=ans[i]; 59 cout <<pr*2-1 <<endl; 60 return 0; 61 }
贴TMP 吧
随性Code