Coprime Integers(莫比乌斯反演)

题目链接:http://codeforces.com/group/NVaJtLaLjS/contest/242322/attachments

题目大意:给你两个区间分别取这个区间中的一个数,使得gcd为1.

思路:考虑莫比乌斯反演,感谢这位大佬https://blog.csdn.net/weixin_43973966/article/details/85338976

 

代码如下:

#include
using namespace std;

const int inf=0x3f3f3f3f;
const int maxn=1e7+17;
bool vis[maxn];
int prim[maxn],mu[maxn],sum[maxn],k;

void get_mu(int n){
  mu[1]=1;
  for(int i=2;i<=n;i++){
    if(!vis[i]){mu[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)break;
      else mu[i*prim[j]]=-mu[i];
    }
  }
  for(int i=1;i<=n;i++)
  sum[i]=sum[i-1]+mu[i];
}
long long Ans(int a,int b){
    a/=k;b/=k;
    int max_rep=min(a,b);
    long long ans=0;
    for(int l=1,r;l<=max_rep;l=r+1){
        r=min(a/(a/l),b/(b/l));
        ans+=(long long)(a/l)*(long long)(b/l)*(long long)(sum[r]-sum[l-1]);
    }
  return ans;
}
int main()
{
    int a,b,c,d;
 	get_mu(maxn-10);
    scanf("%d%d%d%d",&a,&b,&c,&d);
    k = 1;
    printf("%lld\n",Ans(b,d)-Ans(b,c-1)-Ans(a-1,d)+Ans(a-1,c-1));
    return 0;
}

 

你可能感兴趣的:(莫比乌斯反演)