您的位置:首页 > 其它

【BZOJ】1014 仪仗队

2015-07-24 10:40 274 查看
【解析】欧拉函数

[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
,pri
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: