zoukankan      html  css  js  c++  java
  • P2158 [SDOI2008]仪仗队 欧拉函数模板

    题目描述

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

      

    现在,C君希望你告诉他队伍整齐时能看到的学生人数。

    输入输出格式

    输入格式:

    共一个数N

    输出格式:

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

    输入输出样例

    输入样例#1: 
    4
    输出样例#1: 
    9

    说明

    【数据规模和约定】

    对于 100% 的数据,1 ≤ N ≤ 40000

    题解:

    欧拉函数PHI(n)表示的是比n小,并且与n互质的正整数的个数(包括1)

    对与这个题来说,我们讲起始点为原点,将正方形分割为2个三角形 ,那么从2开始向上每行的数量等于他的欧拉函数,

    #include <bits/stdc++.h>
    using namespace std;
    const int size=40010,N=40010;
    const int MAXN=40010;
    int gcd(int a,int b) {
        return b==0?a:gcd(b,a%b);
    }
    int euler[size];
    int phi[MAXN],prime[MAXN],mark[MAXN];
    void Init()//O(n^2)
    {
        memset(euler,0,sizeof(euler));
        euler[1]=1;
        for(int i=2;i<size;i++)
            if(!euler[i])
                for(int j=i;j<size;j+=i)
                {
                    if(!euler[j])
                        euler[j]=j;
                    euler[j]=euler[j]/i*(i-1);//先进行除法是为了防止中间数据的溢出
                }
    }
    int tot;
    void getphi()//这个复杂度好像是O(n)
    {
        int i,j;
        phi[1]=1;
        for(i=2;i<=N;i++)//相当于分解质因式的逆过程
        {
            if(!mark[i])
            {
                prime[++tot]=i;//筛素数的时候首先会判断i是否是素数。
                phi[i]=i-1;//当 i 是素数时 phi[i]=i-1
            }
            for(j=1;j<=tot;j++)
            {
                if(i*prime[j]>N)  break;
                mark[i*prime[j]]=1;//确定i*prime[j]不是素数
                if(i%prime[j]==0)//接着我们会看prime[j]是否是i的约数
                {
                    phi[i*prime[j]]=phi[i]*prime[j];break;
                }
                else  phi[i*prime[j]]=phi[i]*(prime[j]-1);//其实这里prime[j]-1就是phi[prime[j]],利用了欧拉函数的积性
            }
        }
    }
    
    int main()
    {
        int a;
        scanf("%d",&a);
        Init();
        getphi();
        if(a==1)
            printf("%d
    ",0);
        else
        {
            int ans=0;
            for (int i = 3; i <=a ; ++i) {
                ans+=phi[i-1];
            }
            printf("%d
    ",ans*2+3);
        }
    
        return 0;
    }
    

      

      

  • 相关阅读:
    矩阵游戏|ZJOI2007|BZOJ1059|codevs1433|luoguP1129|二分图匹配|匈牙利算法|Elena
    BZOJ3262: 陌上花开
    BZOJ1176: [Balkan2007]Mokia
    BZOJ1261: [SCOI2006]zh_tree
    BZOJ2004: [Hnoi2010]Bus 公交线路
    BZOJ1066: [SCOI2007]蜥蜴
    BZOJ1294: [SCOI2009]围豆豆Bean
    BZOJ2756: [SCOI2012]奇怪的游戏
    BZOJ1857: [Scoi2010]传送带
    BZOJ1237: [SCOI2008]配对
  • 原文地址:https://www.cnblogs.com/-xiangyang/p/9475100.html
Copyright © 2011-2022 走看看