ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1295D Same GCDs

2020-01-30 11:51:08  阅读:357  来源: 互联网

标签:frac gcd ll long Same ans CF1295D 互质 GCDs


我的blog

题目链接:CF1295D Same GCDs

\[description\]

给定\(a,m\),求出有多少个\(x\)满足\(0\leq 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)\)

\(\therefore d|x\)

结论1:

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

证明:

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

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

此时
\[gcd(a+x,m)=gcd(\frac{a+x}{d}\times d,\frac{m}{d}\times d)>d\]

即\(gcd(a+x,m)\neq 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+k\frac{m}{d})\ mod\ \frac{m}{d},\frac{m}{d})=gcd(p,\frac{m}{d})=1\]

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

对于当\(a+x\leq m\),答案是\(\frac{a}{d}\leq x\leq \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)=n\prod _ {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(T\sqrt n)\)

\[code\]

#include<cstdio>
#define re register
#define ll long long
using namespace std;
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()
{
    scanf("%d",&T);
    while(T--)
    {
        ll a,m;
        scanf("%lld%lld",&a,&m);
        ll gcdd=gcd(a,m);
        m/=gcdd;
//  printf("%d\n",gcdd);
        printf("%lld\n",Eular(m));
    }
 
    return 0;
}

标签:frac,gcd,ll,long,Same,ans,CF1295D,互质,GCDs
来源: https://www.cnblogs.com/wangjunrui/p/12242400.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有