zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 26 E

    数论题还是好恶心啊。

    题目大意:给你两个不超过1e12的数 x,y,定义一个f ( x, y ) 如果y==0 返回 0 否则返回1+ f ( x , y - gcd( x , y ) );

    思路:我们设gcd ( x , y) 为G,那么 设 x  = A*G,y = B*G,我们考虑减去多少个G时x y 的gcd会改变,我们设减去

    k个G的时候 x和y 的gcd为改变,即 A*G 和 ( B - k ) * G 的 gcd 改变了,什么情况下会改变呢,就是A 和( B -  k )的gcd

    不为 1 ,这样我们就不断地找出 k 就能得出答案。那么现在问题变成了怎么快速地求出 k ,我们设 A 中的某个因子为

    r,则( B - k )%r == 0 , 设( B - k ) / r的商为 q ,则 B - k = q * r  变形一下变成,B = k + q * r ,两边对 r  取余,B % r = k

    这样我们就能用 B 和 A中的质因数求出 k ,那么我们每次需要记录的就是,B 是 A和B的gcd 的多少倍就,以及A的没有被

    用过的质因数。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll a,b,ans=0;
    vector<ll> va;
    void work(ll y)// y值表示目前 b的值为 gcd(a,b)的y倍。
    {
        if(y==0) return;
        ll k=y;
        for(int i=0;i<va.size();i++)
        {
            k=min(k,y%va[i]);
        }
        ans+=k;y-=k;
        vector<ll> vb;
        for(int i=0;i<va.size();i++)
        {
            if(y%va[i]==0) y/=va[i];
            else vb.push_back(va[i]);//没有用过的a的质因数。
        }
        va=vb;
        work(y);
    }
    int main()
    {
        cin>>a>>b;
        ll gcd=__gcd(a,b);
        a/=gcd;b/=gcd;//保证了a和b没有公共的因子。
        for(ll i=2;i*i<=a;i++)
        {
            while(a%i==0)
            {
                va.push_back(i);
                a/=i;
            }
        }
        if(a>1) va.push_back(a);
        for(int i=0;i<va.size();i++) printf("%d ",va[i]);
        work(b);
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7297754.html
Copyright © 2011-2022 走看看