欧拉函数:解决与小于等于m与m互质的数的个数
void euler(int n)
{
phi[1]=1;//1要特判
for (int i=2;i<=n;i++)
{
if (flag[i]==0)//这代表i是质数
{
prime[++num]=i;
phi[i]=i-1;
}
for (int j=1;j<=num&&prime[j]*i<=n;j++)//经典的欧拉筛写法
{
flag[i*prime[j]]=1;//先把这个合数标记掉
if (i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];//若prime[j]是i的质因子,则根据计算公式,i已经包括i*prime[j]的所有质因子
break;//经典欧拉筛的核心语句,这样能保证每个数只会被自己最小的因子筛掉一次
}
else phi[i*prime[j]]=phi[i]*phi[prime[j]];//利用了欧拉函数是个积性函数的性质
}
}
}
给道板题
Visible Lattice Points[poj3090]
描述
从原点看第一象限的所有整数坐标点,能直接看到的点的数目是多少(不包含原点)
输入
多组数据 第一行表示测试数据组数C(1<=C<=1000)
接下来C行,每行一个整数N(1<=N<=1000),表示范围
输出
C行,每行一个整数
样例输入 [复制]
4
2
4
5
231
样例输出 [复制]
5
13
21
32549
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int data=0;int w=1; char ch=0;
ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0' && ch<='9') data=(data<<3)+(data<<1)+ch-'0',ch=getchar();
return data*w;
}
const int N=100010;
int phi[N],prime[N];
int f[N];
int flag[N];
int num=0;
int c,ans;
inline void eruler(int n){
phi[1]=1;
for(int i=2;i<=n;i++){
if(flag[i]==0){
prime[++num]=i;
phi[i]=i-1;
}
for(int j=1;j<=num&&prime[j]*i<=n;j++){
flag[i*prime[j]]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j]; break;
}
else phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
}
inline void pre(int n){
f[1]=2;
for(int i=2;i<=n;i++){
f[i]=f[i-1]+phi[i];
}
return;
}
int main(){
c=read();
eruler(1000);
pre(1000);
for(int i=1;i<=c;i++){
int n=read();
printf("%d\n",f[n]*2-1);
}
return 0;
}