【BZOJ】1014 儀仗隊

【解析】歐拉函數

[Analysis]
以C君所處的地點爲原點,
向東以x軸正方向,
向北以y軸正方向,
建立平面直角座標系。

當x=0或y=0時,有兩個解。

當x>0且y>0時,
即求有多少條直線y=kx。
設k=a/b,a,b爲整數,
又轉化爲求有多少對a,b,滿足gcd(a,b)=1,1<=a<n,1<=b<n

當a=b時,有a=1,b=1這一組。

接着不妨設a>b,
那麼就相當於求比a小且與a互質的正整數的個數即phi(a)。
歐拉篩法線性求出phi(i)。
共有∑phi(i),2<=i<n個。

同理對於a<b,也有∑phi(i),2<=i<n個。

所以共有2*∑phi(i)+3個,2<=i<n。

時間複雜度:O(n)
空間複雜度:O(n)

[小結]
複習了歐拉函數:
①定義
②性質
③求法 [1]分解法 [2]篩法

[代碼]
/**************************************************************
    Problem: 2190
    User: y20070316
    Language: C++
    Result: Accepted
    Time:32 ms
    Memory:1116 kb
****************************************************************/
 
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
 
const int N=40001;
 
int n;
int phi[N],pri[N];
int res;
 
int main(void)
{
    scanf("%d",&n);
    for (int i=2;i<=n;i++)
    {
        if (!phi[i]) phi[i]=i-1,pri[++pri[0]]=i;
        for (int j=1;j<=pri[0];j++)
        {
            if (i*pri[j]>n) break;
            phi[i*pri[j]]=phi[i]*phi[pri[j]];
            if (i%pri[j]==0) {phi[i*pri[j]]+=phi[i];break;}
        }
    }
     
    for (int i=2;i<n;i++) res+=phi[i];
    res=res+res+3;
    printf("%d\n",res);
     
    return 0;
}

發佈了137 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章