zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 81 (Rated for Div. 2)

    题目链接:Same GCDs

    题意:给你两个数$a$,$m(1 leq a < m leq 10^{10})$,求有多少个$x$满足:$0 leq x < m$且$gcd(a,m)=gcd(a+x,m)$

    思路:设$gcd(a,m)=d$,那么问题转换为求多少个$k in [a,a+m)$满足$gcd(k,m)=d$

    两边同时除$d$,转换为求有多少$k in [frac{a}{d},frac{a+m}{d})$满足$gcd(k,frac{m}{d})=1$

    设$x=frac{a}{d}$,$y=frac{m}{d}$,因为$a<m$,所以显然有$x<y$

    问题转换为求有多少$k in [x,x+y)$满足$gcd(k,y)=1$

    将区间$[x,x+y)$拆成$[x,y]$和$(y,x+y)$两个区间

    • 考虑区间$(y,x+y)$,$gcd(k,y)=gcd(y,k\%y)=gcd(k\%y,y)=1$,因为$k in (y,x+y)$,所以答案为$(0,x)$内与$y$互质的数的个数
    • 考虑区间$[x,y]$,因为$gcd(k,y)=1$,所以答案为$[x,y]$内与$y$互质的数的个数

    两个区间一合并,答案就是$varphi(y)$,即$varphi(frac{d}{m})$

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
     
    using namespace std;
     
    typedef long long ll;
     
    int t;
    ll a, m;
     
    ll gcd(ll a, ll b)
    {
        return 0 == b ? a : gcd(b, a % b);
    }
     
    ll euler(ll n)
    {
        ll ans = n;
        for (ll i = 2; i <= sqrt(n); i++) {
            if (0 == n % i) {
                ans = ans / i * (i - 1);
                while (0 == n % i) n /= i;
            }
        }
        if (n > 1) ans = ans / n * (n - 1);
        return ans;
    }
     
    int main()
    {
        scanf("%d", &t);
        while (t--) {
            scanf("%lld%lld", &a, &m);
            printf("%lld
    ", euler(m / gcd(a, m)));
        }
        return 0;
    }
  • 相关阅读:
    Hadoop压缩
    Hive数据倾斜总结
    DQL、DML、DDL、DCL
    HashMap/HashSet,hashCode,哈希表
    HashMap详解
    Hive分区和桶
    String不可变StringBuffer可变
    Java线程和守护进程
    Ambari安装小记
    P3
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/12257853.html
Copyright © 2011-2022 走看看