题目描述
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.
输入格式
一个整数N
输出格式
答案
输入输出样例
输入 #1
4
输出 #1
4
说明/提示
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
来源:bzoj2818
本题数据为洛谷自造数据,使用CYaRon耗时5分钟完成数据制作。
解释:∑p∈prime∑i=1n∑j=1n[gcd(i,j)=p]=∑p∈prime∑i=1⌊np⌋∑j=1⌊np⌋[gcd(i,j)=1]=∑p∈prime∑i=1⌊np⌋(2∗∑j=1i[gcd(i,j)=1]−1)∑_{p∈prime}∑_{i=1}^n∑_{j=1}^n[gcd(i,j)=p]=∑_{p∈prime}∑_{i=1}^{\lfloor \frac{n}{p} \rfloor }∑_{j=1}^{\lfloor \frac{n}{p} \rfloor }[gcd(i,j)=1]=∑_{p∈prime}∑_{i=1}^{\lfloor \frac{n}{p} \rfloor }(2*∑_{j=1}^{i}[gcd(i,j)=1]-1)∑p∈prime∑i=1n∑j=1n[gcd(i,j)=p]=∑p∈prime∑i=1⌊pn⌋∑j=1⌊pn⌋[gcd(i,j)=1]=∑p∈prime∑i=1⌊pn⌋(2∗∑j=1i[gcd(i,j)=1]−1)
=∑p∈prime∑i=1⌊np⌋(2∗Φ(i)−1)=∑_{p∈prime}∑_{i=1}^{\lfloor \frac{n}{p} \rfloor }(2*\Phi(i)-1)=∑p∈prime∑i=1⌊pn⌋(2∗Φ(i)−1),我们o(n)o(n)o(n)预处理出来素数和欧拉函数前缀和,直接就可以计算啦
#include<iostream>
using namespace std;
const int inf=0x7fffffff;
const double eps=1e-10;
inline int read(){
int x=0,f=1;char ch;ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=0;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch&15);ch=getchar();}
if(f)return x;else return -x;
}
const int N=10000010;
bool vis[N];
long long prim[N],phi[N];
void get_phi(int n){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){phi[i]=i-1;prim[++prim[0]]=i;}
for(int j=1;j<=prim[0]&&i*prim[j]<=n;j++){
vis[i*prim[j]]=1;
if(i%prim[j]==0){phi[i*prim[j]]=phi[i]*prim[j];break;}
else phi[i*prim[j]]=phi[i]*(prim[j]-1);
}
}
for(int i=1;i<=n;i++) phi[i]+=phi[i-1];
}
int n;
long long ret=0;
int main(){
get_phi(10000000);
n=read();
for(int i=1;i<=prim[0]&&prim[i]<=n;i++){
ret+=2*phi[n/prim[i]]-1;
}
cout<<ret<<endl;
return 0;
}

被折叠的 条评论
为什么被折叠?



