• Codeforces 1295 D. Same GCDs


    Codeforces 1295 D. Same GCDs

    题意:

    给定两个整数(a,mleq10^{10})

    问有多少个(0leq x<m)(gcd(a,m)=gcd(a+x,m))

    思路:

    把结果写成表达式

    [sum_{x=0}^{m-1}[gcd(a,m)=gcd(a+x,m)] ]

    根据gcd的计算过程有:

    [sum_{x=0}^{m-1}[gcd(a,m)=gcd((a+x)mod m, m)] ]

    我们知道(x)的取值范围在([0,m-1]),其实就是相当于把(a)在数轴上向右平移了这么多个单位,取模之后又回到了([0,m-1])的区间。

    所以有

    [sum_{i=0}^{m-1}[gcd(i,m)=gcd(a,m)] ]

    提取(gcd(a,m)=d)

    [sum_{i=0}^{m-1}[gcd(i,m)=g]\sum_{0leq i<m}^{g|i}[gcd(frac{i}{g},frac{m}{g})=1] ]

    这个就是(varphi(frac{m}{g}))

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll a, m;
    ll phi(ll x)
    {
        ll res = x;
        for(ll i = 2; i <= x/i; i++)
        {
            if(x % i == 0)
            {
                res = res/i*(i-1);
                while(x%i == 0) x /= i;
            }
        }
        if(x > 1) res = res/x*(x-1);
        return res;
    }
    
    ll gcd(ll a, ll b){
        if(b == 0) return a;
        return gcd(b, a%b);
    }
    
    void solve()
    {
        cin >> a >> m;
        ll k = gcd(a, m);
        cout << phi(m/k) << endl;
    }
    
    int main()
    {
        int T; scanf("%d", &T);
        while(T--) solve();
    }
    
    
  • 相关阅读:
    显示AVI的第一桢
    视频采集,存成avi
    视频捕获
    如何将Wav文件做到EXE文件里
    图形整体拉出效果
    3.2 指数型生成函数
    3.1 普通型生成函数
    诡异的楼梯 HDU
    A strange lift HDU
    胜利大逃亡 HDU
  • 原文地址:https://www.cnblogs.com/zxytxdy/p/12262375.html
Copyright © 2020-2023  润新知