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
  • 相关阅读:
    logback配置模板
    mail
    jpa,querydsl
    加密签名
    angular2快速开始
    主从复制
    随笔
    缺货源的小伙伴们 我发现一个超级好的货源供应链 分享给大家
    canal+kafka+logstash+es 架构 logstash的配置
    golang 根据图片url获取图片尺寸
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7297754.html
Copyright © 2011-2022 走看看