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;
    }
  • 相关阅读:
    一个简单粗暴的爬虫
    Linux 目录结构
    python 部署 Restful web
    JVM 运行时数据区总结 栈 堆 堆大小配置总结
    成都法律援助申请流程
    JavaEE error整理(不断更新)
    ehcache.xml 属性大全
    SpringMVC 构建Restful风格 及问题处理
    Http Content-Type
    Redis 教程 Java工程师学习知识点
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/12257853.html
Copyright © 2011-2022 走看看