码迷,mamicode.com
首页 > 其他好文 > 详细

[SDOI2008]仪仗队(欧拉筛裸题)

时间:2018-06-09 11:25:56      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:text   log   重复   mes   ==   更新   分享图片   load   分享   

题目描述

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

输入输出格式

输入格式:

 

共一个数N

 

输出格式:

 

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

思路:

典型的欧拉筛

为了帮助萌新,我先从欧拉函数开讲

什么是欧拉函数?

定义:与一个数的约数有且只有1的数(互质)的个数(比如说2有1一个,6有1,5两个)

性质:积性函数(Phi(i)等于他的所有质因数的phi值的乘积)

为什么能这么做呢?

其实这道题求的是有多少种不同的斜率

为什么呢?

看图:

技术分享图片

很显然,一个斜率上只能看到一个人,该斜率其他人都会被堵得死死的。。。

那么,每一个独立的斜率又如何表示呢?

我们用数对(x,y)表示斜率

我们知道,如果x,y不互质,那么他们可以同时除以他们的最大公约数(设为k),则该斜率可表示为(x/k,y/k)

很显然会有重复

所以为了避免重复,我们所求的是互质点对的个数

互质点对很显然就是欧拉函数

这里我用的是(nlogn)的算法——埃氏筛

从2开始,一个数i如果因数标记为1,则他是素数,他的欧拉函数值为i-1,同时,利用它来更新所有它的倍数的因数标记,如果因数标记大于1,则其不是素数,根据积性函数的性质,Phi[i]=其各因数的乘积,当其含有多次方因子时(比如8=2^3),那么Phi[i]的值为phi[2]*2*2;

不说了,代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
long long ll;
long long e[40010];
long long n,ans;
int main()
{
    ans=2;
    cin>>n;
    if(n==1)
    {
        cout<<0;
        return 0;
    }
    for(int i=1;i<=n;++i)
    {
        e[i]=i;
    }
    for(int i=2;i<=n;++i)
    {
        if(e[i]==i)
        {
            for(int j=i;j<=n;j+=i)
            {
                e[j]=e[j]/i*(i-1);
            }
        }
    }
    n--;
    for(int i=2;i<=n;++i)
    {
        ans+=e[i]*2;
    }
    cout<<ans+1;
}        

[SDOI2008]仪仗队(欧拉筛裸题)

标签:text   log   重复   mes   ==   更新   分享图片   load   分享   

原文地址:https://www.cnblogs.com/ztz11/p/9059526.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!