【BZOJ】1014 仪仗队

来源:互联网 发布:ubuntu停止当前命令 编辑:程序博客网 时间:2024/06/05 02:28
【解析】欧拉函数

[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;}

0 0
原创粉丝点击