zoukankan      html  css  js  c++  java
  • 【Luogu】P2158仪仗队(欧拉函数)

    题目链接

    首先来介绍欧拉函数。

    设欧拉函数为f(n),则f(n)=1~n中与n互质的数的个数。

    欧拉函数有三条引论:

    1.若n为素数,则f(n)=n-1;

    2.若n为pa,则f(n)=(p-1)*(pa-1)。

    3.若gcd(a,b)=1,则f(a*b)=f(a)*f(b)。

    下面代码给出欧拉函数的求法。可以和线性筛结合。

    for(register int i=2;i<n;++i){
            if(!f[i]){
                prime[++num]=i;
                phi[i]=i-1;
            }
            for(int j=1;j<=num&&prime[j]*i<n;++j){
                f[i*prime[j]]=1;
                if(!(i%prime[j])){
                    phi[i*prime[j]] = phi[i] * prime[j];
                    break;
                }
                phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }

    phi数组是欧拉函数值。

    那欧拉函数和本题有什么关系呢?

    我们知道对于坐标点(i*k,j*k),它一定会被点(i,j)阻挡。

    换句话说设i*k=a,j*k=b。

    只要gcd(a,b)!=1则会被阻挡。

    因此要求的是范围内满足条件gcd(a,b)=1的点(a,b)有多少个。

    因为正方形关于对角线对称,所以可以只算左下部分,右上部分是和左下部分相等的。

    因为是左下部分,所以a>=b。

    原题变成了求∑phi(i),其中i=1~n。

    代码如下。

    #include<cstdio>
    #include<cctype>
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    int prime[40010],num;
    bool f[40010];
    bool d[40010];
    int phi[40010];
    int ans;
    int main(){
        int n=read();
        for(register int i=2;i<n;++i){
            if(!f[i]){
                prime[++num]=i;
                phi[i]=i-1;
            }
            for(int j=1;j<=num&&prime[j]*i<n;++j){
                f[i*prime[j]]=1;
                if(!(i%prime[j])){
                    phi[i*prime[j]] = phi[i] * prime[j];
                    break;
                }
                phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
        for(register int i=2;i<n;++i) ans+=phi[i];
        printf("%d",ans*2+3);
        return 0;
    }
  • 相关阅读:
    Redis学习手册(String数据类型)
    Redis学习手册(开篇)
    android判断当前应用程序处于前台还是后台
    android EditText输入变化事件详解
    Android. Scrolling 2 listviews together
    Android ListView快速定位(四)
    使用【百度云推送】第三方SDK实现推送功能具体解释
    SDN:软件定义网络
    MATLAB中导入数据:importdata函数
    JSP中Session的使用
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/7487919.html
Copyright © 2011-2022 走看看