[SDOI2008]仪仗队

传送门

这道题很重要的是分析。

我们从(0,0)开始标号,最后格子为(n-1,n-1)。

一个点(x,y)如果看不到,说明x,y互质。

因为两半具有对称性,所以我们只用算一半。

求与x互质的个数,即是phi(x),预处理phi即可。

除了(1,1)(1,0)(0,1),其余用phi累加即可。

注意:1的特判,线性筛时N开大一点或者写<N而不是<=N。

#include<bits/stdc++.h>
#define LL long long
#define re register 
#define N 40020//开大一点
using namespace std;
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
void print(int x)
{
    if(x<0)x=-x,putchar('-');
    if(x>9)print(x/10);
    putchar(x%10+'0');
}
int phi[N],prime[N],notp[N];
int tot=0;
void init()
{
    for(int i=2;i<=N;++i)
    {
        if(!notp[i])prime[++tot]=i,phi[i]=i-1;
        for(int j=1;j<=tot&&i*prime[j]<=N;++j) 
        {
            notp[prime[j]*i]=1;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
}
int main()
{
    init();
    int n=read();
    LL ans=0;
    for(int i=2;i<n;++i)ans+=phi[i];
    ans=ans*2;
    ans+=3;
    if(n==1)ans=0;
    printf("%lld
",ans);
}
View Code
原文地址:https://www.cnblogs.com/yyys-/p/11680295.html