• CF1295D Same GCDs


    我的blog

    题目链接:CF1295D Same GCDs

    本文版权归博客园和蒟蒻wjr所有,欢迎转载,但需保留此段声明,并给出原文链接,如有侵权行为,还请不吝啬向博主举报,谢谢合作。

    [description ]

    给定(a,m),求出有多少个(x)满足(0leq x<m)

    [gcd(a,m)=gcd(a+x,m) ]

    (gcd(x,y))表示(x)(y)的最大公因数

    [solution ]

    数论题

    考虑设(d=gcd(a,m))

    肯定满足(d|a,d|m,d|(a+x))

    ( herefore d|x)

    结论1:

    [gcd(frac{a+x}{d},frac{m}{d})=1 ]

    证明:

    假设(gcd(frac{a+x}{d},frac{m}{d}) eq 1)

    (gcd(frac{a+x}{d},frac{m}{d})> 1)

    此时

    [gcd(a+x,m)=gcd(frac{a+x}{d} imes d,frac{m}{d} imes d)>d ]

    (gcd(a+x,m) eq gcd(a,m))

    互相矛盾

    综上所述:(gcd(frac{a+x}{d},frac{m}{d})=1)成立

    结论2:

    答案是

    [varphi(frac{m}{d}) ]

    显然对与任意与m互质的数(p)和任意正整数(k)
    满足:

    [gcd(p+frac {km}{d},frac{m}{d})=gcd((p+kfrac{m}{d}) mod frac{m}{d},frac{m}{d})=gcd(p,frac{m}{d})=1 ]

    显然(p+frac {km}{d})(frac{m}{d})互质

    对于当(a+xleq m),答案是(frac{a}{d}leq xleq frac{m}{d})的与(frac{m}{d})互质的个数

    对于与(m<a+x<a+m),答案是(x<frac{a}{d})的与(frac{m}{d})互质的个数

    两个答案区间合并即是(varphi(frac{m}{d}))

    欧拉函数:

    其中(p_1, p_2……p_k)(n)的所有质因数,(n)是不为(0)的整数。(varphi(1)=1)(唯一和(1)互质的数就是(1)本身)。

    [varphi(n)=nprod _ {i=1}^{k}(1-frac{1}{p_i}) ]

    因为n最多有一个大于(sqrt{n})的质因数

    所以可以得到以下代码

    inline long long Eular(long long n)
    {
    	long long ans=n;
    	for(re int i=2; 1ll*i*i<= n; i++)
    	{
    		if(n%i==0)
    		{
    			ans-=ans/i;
    			while(n%i==0)
    				n/=i;
    		}
    	}
    	if(n>1)
    		ans-=ans/n;
    	return ans;
    }
    

    欧拉函数复杂度(O(sqrt n))

    算法总复杂度(O(Tsqrt n))

    [code ]

    #include<cstdio>
    #define re register
    #define ll long long
    using namespace std;
    template<typename T>
    inline void read(T&x)
    {
    	x=0;
    	char s=(char)getchar();
    	bool flag=false;
    	while(!(s>='0'&&s<='9'))
    	{
    		if(s=='-')
    			flag=true;
    		s=(char)getchar();
    	}
    	while(s>='0'&&s<='9')
    	{
    		x=(x<<1)+(x<<3)+s-'0';
    		s=(char)getchar();
    	}
    	if(flag)
    		x=(~x)+1;
    	return;
    }
    inline ll gcd(ll a,ll b)
    {
    	return b==0?a:gcd(b,a%b);
    }
     
    inline long long Eular(long long n)
    {
    	long long ans=n;
    	for(re int i=2; 1ll*i*i<= n; i++)
    	{
    		if(n%i==0)
    		{
    			ans-=ans/i;
    			while(n%i==0)
    				n/=i;
    		}
    	}
    	if(n>1)
    		ans-=ans/n;
    	return ans;
    }
    int T;
    int main()
    {
    	read(T);
    	while(T--)
    	{
    		ll a,m;
    		read(a),read(m);
    		printf("%lld
    ",Eular(m/gcd(a,m)));
    	}
     
    	return 0;
    }
    
    
    
    
  • 相关阅读:
    svn随笔
    关于PHP调用IE的Com组件的一些要求
    Bash总结
    Firefox常用扩展
    proftpd的一些简单配置
    lua积累
    backbone.js源码解析:extend、Backbone.View
    Ubuntu 12.04LTS 安装VMwareWorkstation
    关于安装Ubuntu不将mbr写入grub的经验
    .NET6发布到linux
  • 原文地址:https://www.cnblogs.com/wangjunrui/p/12242400.html
Copyright © 2020-2023  润新知