• 【HDU1695】GCD(莫比乌斯反演)


    【HDU1695】GCD(莫比乌斯反演)

    题面

    题目大意

    (a<=x<=b,c<=y<=d)
    (gcd(x,y)=k)的无序数对的个数
    其中,你可以假定(a=c=1)
    所有数都(<=100000)
    数据组数(<=3000)

    题解

    莫比乌斯反演

    作为一道莫比乌斯反演的题目
    首先我们要迈出第一步
    如果有(gcd(x,y)=k)
    那么,我们就有(gcd(frac{x}{k},frac{y}{k})=1)
    所以,现在问题相当于转化为了求
    (x<=frac{b}{k},y<=frac{d}{k})
    (x,y)互质的组数

    (f(i))表示(gcd(u,v)=i)的个数(有序)
    (g(i)=sum_{i|d}f(i)),表示(gcd(u,v)=ki,k∈Z)的个数
    很容易的,(g(i)=(frac bk/i)·(frac dk/i))
    通过莫比乌斯反演就可以直接计算啦
    时间复杂度(O(T·n),n=min(a,b))
    再提一句,因为是无序的数对
    所以要减去重复计算的地方。。。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAX 101000
    inline int read()
    {
        int x=0,t=1;char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int mu[MAX],pri[MAX],tot;
    long long g[MAX],n,a,b,K;
    bool zs[MAX];
    void Get()
    {
        zs[1]=true;mu[1]=1;
    	for(int i=2;i<=n;++i)
    	{
    		if(!zs[i])pri[++tot]=i,mu[i]=-1;
    		for(int j=1;j<=tot&&i*pri[j]<=n;++j)
    		{
    			zs[i*pri[j]]=true;
    			if(i%pri[j])mu[i*pri[j]]=-mu[i];
    			else {mu[i*pri[j]]=0;break;}
    		}
    	}
    }
    int main()
    {
    	n=100000;
    	Get();
    	int T=read(),Case=0;
    	while(T--)
    	{
    		cout<<"Case "<<++Case<<": ";  
    		read();a=read();read();b=read();K=read();
    		if(!K){puts("0");continue;}
    		a/=K;b/=K;
    		long long ans=0,mi=0;
    		for(int i=1;i<=min(a,b);++i)g[i]=1ll*(a/i)*(b/i);
    		for(int i=1;i<=min(a,b);++i)ans+=1ll*mu[i]*g[i];
    		for(int i=1;i<=min(a,b);++i)mi+=1ll*mu[i]*(min(a,b)/i)*(min(a,b)/i);
    		printf("%lld
    ",ans-mi/2);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Leetcode888. 公平的糖果棒交换
    Leetcode81. 搜索旋转排序数组 II
    Leetcode80. 删除排序数组中的重复项 II
    Leetcode1631. 最小体力消耗路径
    Leetcode57. 插入区间
    Leetcode724. 寻找数组的中心索引
    Leetcode18. 四数之和
    Leetcode110. 平衡二叉树
    Leetcode1128. 等价多米诺骨牌对的数量
    python 集合和深浅copy
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7954364.html
Copyright © 2020-2023  润新知