zoukankan      html  css  js  c++  java
  • Codeforces 1295D Same GCDs (欧拉函数)

    传送门

    题意:

    给两个整数a,m (( 1 le a < m le 10^{10} ).)
    问有多少个x满足 (0 le x < m ,gcd(a, m) = gcd(a + x, m) .)
    输出满足上式x的个数

    思路:

    令p=(gcd(a, m)),
    (0 le x < m ,gcd(a, m) = gcd(a + x, m) .)相等的个数等于(1 le x <= m ,gcd(a, m) = gcd( x, m) .)
    证明:前提(gcd(a,b) = gcd(b,a mod b))
    (0 le x < m ,gcd(a, m) = gcd(a + x, m) .)(a le k < a+m ,gcd(a, m) = gcd(k, m) .)
    [a,a+m),可分成[a,m],[m+1,a+m)
    根据前提:[m+1,a+m)和[1,a)的gcd个数应该相等
    所以k(in)[a,a+m),(gcd(k,m)==gcd(a,m))k(in)[1,m],(gcd(k,m)==gcd(a,m))的个数
    然后即求(1 le k <= m ,gcd(k/p,m/p)==1),很明显该值为m/p欧拉函数的值,直接用欧拉函数的模版求即可,O((sqrt(n)))

    代码:

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    #include <math.h>
    #include <map>
    #include <queue>
    #include <set>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+50;
    ll gcd(ll a,ll b){
        return b?gcd(b,a%b):a;
    }
    void solve(ll m){
        ll ans=m;
        for(ll i=2;i*i<=m;i++){
            if(m%i==0){
                ans-=(ans/i);
                while(m%i==0)m/=i;
            }
        }
        if(m>1)ans-=ans/m;
        printf("%lld
    ",ans);
    }
    int main()
    {
        int t;
        ll m,a;
        scanf("%d",&t);
        while(t--){
            scanf("%lld %lld",&a,&m);
            ll p=gcd(a,m);
            m/=p;
            solve(m);
        }
        return 0;
    }
    
  • 相关阅读:
    zabbix 主被动模式
    MySQL角色(role)功能介绍
    MySQL权限管理实战
    创建索引,这些知识应该了解
    MySQL锁等待与死锁问题分析
    Navicat操作MySQL简易教程
    职场里,对数据库要有敬畏之心!
    MySQL字段默认值设置详解
    MySQL查看及杀掉链接方法大全
    MySQL字段类型最全解析
  • 原文地址:https://www.cnblogs.com/zzl_Alexander/p/12250650.html
Copyright © 2011-2022 走看看