BZOJ 2820 YY的GCD(莫比乌斯函数)

来源:互联网 发布:use女装知乎 编辑:程序博客网 时间:2024/04/29 11:51

给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对


以前的容斥原理解法必然TLE,这里就得用到莫比乌斯函数(了解莫比乌斯函数请戳这里)

对于这题而言,枚举质数也会是TLE的节奏。。。


/**************************************************************    Problem: 2820    User: too_weak    Language: C++    Result: Accepted    Time:5244 ms    Memory:166820 kb****************************************************************/ #include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn =10000000+5;typedef long long LL;int primes,prime[maxn],mu[maxn],g[maxn],sum[maxn];void init(){    static bool vis[maxn];    memset(vis,0,sizeof(vis));    mu[1]=1;primes=0;    for(int i=2;i<maxn;i++)    {        if(!vis[i])            prime[primes++]=i,mu[i]=-1,g[i]=1;        for(int j=0;j<primes&&i*prime[j]<maxn;j++)        {            vis[i*prime[j]]=1;            if(i%prime[j])                mu[i*prime[j]]=-mu[i],g[i*prime[j]]=mu[i]-g[i];            else            { mu[i*prime[j]]=0;g[i*prime[j]]=mu[i];break;}        }    }    sum[0]=0;    for(int i=1;i<maxn;i++)        sum[i]=sum[i-1]+g[i];}int main(){    init();    int T;    scanf("%d",&T);    while(T--)    {        LL n,m;        scanf("%lld%lld",&n,&m);        if(n>m) swap(n,m);        LL ans=0;        for(int i=1,last;i<=n;i=last+1)        {            last=min(n/(n/i),m/(m/i));            ans+=(n/i)*(m/i)*(sum[last]-sum[i-1]);        }        printf("%lld\n",ans);    }    return 0;}


原创粉丝点击