bzoj2190: [SDOI2008]仪仗队

Description

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

Input

  共一个数N。

Output

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

Sample Input

  4

Sample Output

  9


HINT

【数据规模和约定】   对于 100% 的数据,1 ≤ N ≤ 40000

——————————————————————————
这道题能看到的点 x y 必然是互质的不然 x/gcd(x,y) y/gcd(x,y) 可以把他挡住
所以我们就求一波 欧拉 2-n-1 然后特殊处理左下角三个点就okay辣
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=40007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int T,n,s[M],cnt;
LL f[M],ans,p[M];
void prepare(){
    p[1]=1;
    for(int i=2;i<M;i++){
        if(!f[i]) s[++cnt]=i,p[i]=i-1;
        for(int j=1,k;j<=cnt&&(k=i*s[j])<M;j++){
            f[k]=1;
            if(i%s[j]) p[k]=p[i]*(s[j]-1);
            else{
                p[k]=p[i]*s[j];
                break;
            }
        }
    }
}
int main()
{
    n=read(); prepare();
    for(int i=2;i<n;i++) ans+=p[i];
    printf("%lld
",ans*2+3);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lyzuikeai/p/7308941.html