bzoj 2818: Gcd

来源:互联网 发布:python str replace 编辑:程序博客网 时间:2024/06/06 15:39

2818: Gcd

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 3381  Solved: 1492
[Submit][Status][Discuss]

Description

给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.

Input

一个整数N

Output

如题

Sample Input

4

Sample Output

4

HINT

hint

对于样例(2,2),(2,4),(3,3),(4,2)


1<=N<=10^7

Source

湖北省队互测


题解:

sigma(枚举质数p) sigma (i=1..n) sigma(j=1..n) [gcd(i,j)==p]

sigma(枚举质数p) sigma(i=1..n) sigma(j=1..n) [gcd(i/p,j/p)==1]

sigma(枚举质数p) sigma(i=1..[n/p](下取整)) sigma(j=1..[n/p]) [(i,j)==1]

sigma(枚举质数p) sigma(i=1..[n/p](下取整)) sigma(j=1..[n/p]) sigma(d=1..[n/p]) [d/i] [d/j] mu(d)

sigma(枚举质数p) sigma(i=1..[n/p](下取整))  [d/i]    sigma(j=1..[n/p])  [d/j]   sigma(d=1..[n/p])  mu(d)

sigma(枚举质数p) 设N=n/p    sigma(d=1....N)  [N/d][N/d](下取整)mu(d)


mu 可以用线性筛来求,sigma(d=1....N)  [N/d][N/d] 看到这个就应该想到分块,因为他只有sqrt(N)个取值,那么我们统计mu的前缀和,然后对于[N/d]相同的部分,直接ans+=[N/d][N/d]*(mu[j]-mu[i-1])

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define N 10000003#define ll long longusing namespace std;long long n;long long p[N],prime[N],mu[N],ans;void calc(){mu[1]=1;for (ll i=2;i<=n;i++){if (!p[i]){prime[++prime[0]]=i;mu[i]=-1;}        for (ll j=1;j<=prime[0];j++)        {        if (prime[j]*i>n) break;        p[prime[j]*i]=1;        if (i%prime[j]==0)         mu[i*prime[j]]=0;        else         mu[i*prime[j]]=-mu[i];        }        mu[i]+=mu[i-1];}}int main(){scanf("%lld",&n);calc();for (ll l=1;l<=prime[0];l++){if (prime[0]>n) break;ll k=n/prime[l]; ll j;for (ll i=1,j=0;i<=k;i=j+1){j=n/(n/i);ans+=(mu[j]-mu[i-1])*(k/i)*(k/i);}}printf("%lld\n",ans);return 0;}



0 0
原创粉丝点击