码迷,mamicode.com
首页 > 其他好文 > 详细

求解范围中 gcd(a,b)== prime 的有序对数

时间:2018-08-31 21:28:16      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:计算   bzoj   oid   要求   font   素数   nta   bsp   整数   

题目:

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

输入:

一个整数N。

 

输出:

如题。

 

Sample  Input
4

Sample Output

4

 

Hint

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

1<=N<=10^7

 

思路:

对于本题,因为是使得技术分享图片为质数,所以必然要枚举小于等于技术分享图片的质数,那么对于每一个质数技术分享图片

需要求在区间技术分享图片中,满足有序对技术分享图片互质的对数。

也就是说,现在问题转化为:在区间技术分享图片中,存在多少个有序对使得技术分享图片互质,这个问题就简单啦,因为

是有序对,不妨设技术分享图片,那么我们如果枚举每一个技术分享图片,小于技术分享图片有多少个技术分享图片技术分享图片互素,这正是欧拉函数。所以

我们可以递推法求欧拉函数,将得到的答案乘以2即可,但是这里乘以2后还有漏计算了的,那么有哪些呢?

技术分享图片且为素数的情况,再加上就行了。

 

另外,在bzoj上好像空间限制的原因要用埃氏筛法筛质数,而在nyzoj上,数据点较大,最好用欧拉筛筛质数。

//nyzoj(乌市一中在线评测) www.nyzoj.com:5283 题目:blcup (10053)

 

代码如下:

//bzoj AC版:

#include<cstdio>
typedef long long ll;
const ll N=1e7+9;
ll n,f[N],phi[N];
bool prime[N];
ll p[N],cnt;
void prework()
{
    for (int i=2;i<=n;i++) prime[i]=1;
    for (int i=2;i<=n;i++)
    {
        if (prime[i])
        {
            p[++cnt]=i;
            for (int j=i<<1;j<=n;j+=i)
              prime[j]=0;
        }
    }
}
void Er()
{
    for (int i=1;i<=n;i++) phi[i]=i;
    for (int i=2;i<=n;i+=2) phi[i]>>=1;
    for (int i=3;i<=n;i+=2)
    {
        if (phi[i]==i)
        for (int j=i;j<=n;j+=i)
          phi[j]=phi[j]-phi[j]/i;
    }
    f[1]=0;
    for (int i=2;i<=n;i++)
      f[i]=f[i-1]+(phi[i]<<1);
}
ll solve()
{
    ll ans=0;
    for (int i=1;i<=cnt;i++)
    {
        ans+= 1 + f[n/p[i]] ;
    }
    return ans;
}
int main()
{
    scanf ("%lld",&n);
    prework();
    Er();
    printf("%lld",solve());
    return 0;
}

 

//nyzoj AC 版:

#include<cstdio>
typedef long long ll;
const ll N=1e7+7;
ll n,f[N],phi[N];
int v[N];
ll p[N],cnt;
void prework()
{
    for (int i=2;i<=n;i++)
    {
        if (v[i]==0)
        {
            v[i]=i; p[++cnt]=i;
        }
        for (int j=1;j<=cnt;j++)
        {
            if (p[j]>v[i] || p[j]>n/i) break;
            v[i*p[j]]=p[j];
        }
    }
}
void Er()//递推求欧拉函数 
{
    for (int i=1;i<=(n>>1);i++) phi[i]=i;
    for (int i=2;i<=(n>>1);i+=2) phi[i]>>=1;
    for (int i=3;i<=(n>>1);i+=2)
    {
        if (phi[i]==i)
        for (int j=i;j<=(n>>1);j+=i)
          phi[j]=phi[j]-phi[j]/i;
    }
    f[1]=0;
    for (int i=2;i<=(n>>1);i++)
      f[i]=f[i-1]+(phi[i]<<1);
}
ll solve()
{
    ll ans=0;
    for (int i=1;i<=cnt;i++)
    {
        ans+= 1 + f[n/p[i]] ;
    }
    return ans;
}
int main()
{
    scanf ("%lld",&n);
    prework();
    Er();
    printf("%lld",solve());
    return 0;
}

 

求解范围中 gcd(a,b)== prime 的有序对数

标签:计算   bzoj   oid   要求   font   素数   nta   bsp   整数   

原文地址:https://www.cnblogs.com/zylAK/p/9567600.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!