题解D. Same GCDs Educational Codeforces Round 81

在这里插入图片描述
题意 给定a,m 求x在[0,m)中有多少数字满足gcd(a,m) =gcd(a+x,m)

思路:
不管怎么样先化简一下, 令P = gcd(a,m), 于是就是求在[a/P,(a+m)/P)中和m/P互质的数字个数。

在一个区间内求互质个数,很容易想到欧拉函数,但是原来的题面和欧拉函数的定义不同

但是可以发现[a/P,(a+m)/P)的区间长度是m/P-1,所以我们想到在这一段区间内的数减去a/P其实就是就[1,m/P),即我们可以得出[a/P,(a+m)/P)中和m/P互质的数字个数其实就是求m/P的欧拉函数
如果不理解可以把这个区间看成一个循环的一节

#include<bits/stdc++.h>
using namespace std;
const int  maxn =1e5+7;
#define ll long long
vector<int>g[30];
ll a,m;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        cin>>a>>m;
        ll gcd = __gcd(a,m);
        ll ans = m/gcd;
        ll q = ans ;
        for(ll i =2;i*i<=q;i++)
        {
            if(q%i == 0)ans = ans -ans /i;
            while(q%i==0)q/=i;
        }
        if(q!=1)ans -=ans /q ;
        cout<<ans<<endl;
    }

	return 0  ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值