给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
一个整数N
如题
hint
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
题意:给一个正整数 N,其中1<=N<=10^7,求使得 gcd(x,y)为质数的 (x,y)对的个数,1<=x,y<=n。
分析:莫比乌斯反演,十分的巧妙。
GCD(a,b)的题十分经典。GCD(a,b)=d (d是素数),但是思想却是相同的。
设f(d) = GCD(a,b) = d的种类数 ;
F(n) 为GCD(a,b) = d 的倍数的种类数,GCD(a,b)%d==0;
即 :F(x) = (N/x)*(N/x);//N中是x的倍数的个数,然后组合
则f(x) = sigma( mu[d/x]*F(d), d|n )
由于d = 1 所以f(1) = sigma( mu[d]*F(p*d) ) = sigma( mu[d]*(N/pd)*(N/pd) ); p为枚举的素数;p*d
so....
初探莫比乌斯。还有很多不是很懂。跟进中。。。
转载请注明出处:寻找&星空の孩子
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2818
#include
#include
#include
using namespace std;
const int MAXN = 1e7+10;
typedef long long LL;
//LL F[MAXN],f[MAXN];
LL pri[MAXN],pri_num;
LL mu[MAXN];//莫比乌斯函数值
bool vis[MAXN];
void mobius(int N) //筛法求莫比乌斯函数
{
pri_num = 0;//素数个数
memset(vis, false, sizeof(vis));
vis[1] = true;
mu[1] = 1;
for(int i = 2; i <=N; i++)
{
if(!vis[i])
{
pri[pri_num++] = i;
mu[i] = -1;
}
for(int j=0; j
我的代码跑了7秒。。。学长的代码跑了6秒。。。仅供参考
/* Language: C++
Result: Accepted
Time:6432 ms
Memory:167288 kb
****************************************************************/
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int maxn = 1e7+1;
bool s[maxn];
int prime[maxn],len = 0;
int mu[maxn];
int g[maxn];
int sum1[maxn];
void init()
{
memset(s,true,sizeof(s));
mu[1] = 1;
for(int i=2; i0)
{
LL sum = 0;
for(int i=1,la = 0 ; i<=a; i = la+1)
{
la = a/(a/i);
sum = sum + (long long)(sum1[la] - sum1[i-1])*(a/i)*(a/i);
}
printf("%lld\n",sum);
}
return 0;
}
网上有其他的解法。。。还快些(5秒)
转载自:http://www.cnblogs.com/chensiang/p/4682706.html
/**************************************************************
Problem: 2818
Language: C++
Result: Accepted
Time:5220 ms
Memory:128224 kb
****************************************************************/
#include
#define clr(a,x) memset(a,x,sizeof(a))
#define rep(i,l,r) for(int i=l;i>1)+1){
if(p[i]){
for(int j=i<<1;j<=n;j+=i){
p[j]=0;
}
}
}
rep(i,2,n+1){
if(p[i]){
s[cnt++]=i;
}
}
}
int main()
{
n=read();
getphi();
getsushu();
ll ans=0;
rep(i,0,cnt){
ans+=f[n/s[i]]*2-1;
}
printf("%lld\n",ans);
return 0;
}
mada...mada...!!!