bzoj 2818: Gcd

Description

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

solution

比较水的题目,如果不是质数,必须得用到 \(O(n\sqrt{n})\)的容斥,但是如果gcd为质数那么存在很多性质....
我们枚举每一个质数,枚举每一个倍数,然后加上 \(phi\) 即可,如果不是倍数不是1,还需要乘以2,样例可以看出

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=10000005;
int n,prime[N],num=0,phi[N];bool vis[N];
void priwork(){
  phi[1]=1;
  for(int i=2;i<=n;i++){
    if(!vis[i])prime[++num]=i,phi[i]=i-1;
    for(int j=1;j<=num && i*prime[j]<=n;j++){
      int to=i*prime[j];vis[to]=1;
      if(i%prime[j]==0){phi[to]=phi[i]*prime[j];break;}
      else phi[to]=phi[i]*(prime[j]-1);
    }
  }
}

void work()
{
  cin>>n;
  priwork();
  ll ans=0;
  for(int i=1;i<=num;i++){
    int lim=n/prime[i];
    for(int j=1;j<=lim;j++){
      if(j==1)ans+=phi[j];
      else ans+=phi[j]<<1;
    }
  }
  printf("%lld\n",ans);
}

int main()
{
  work();
  return 0;
}

posted @ 2017-11-06 14:49  PIPIBoss  阅读(159)  评论(0编辑  收藏  举报