• Codeforces 837E. Vasya's Function


     题意:

    • f(a, 0) = 0;
    • f(a, b) = 1 + f(a, b - gcd(a, b))
    • 输出f(a,b)

    a=A*gcd(a,b)    b=B*gcd(a,b)

    一次递归后,变成了 f(A*gcd(a,b),(B-1)*gcd(a,b))

    若gcd(A,(B-1))=1,那么 这一层递归的gcd(a,b)仍等于上一层递归的gcd(a,b)

    也就是说,b-gcd(a,b),有大量的时间减的gcd(a,b)相同,

    若计算出减了S次相同的gcd(a,b)

    那就可以直接由f(a,b)到 f(a,b-S*gcd(a,b))+ S

    设T是A的任意因子

    那么S满足 (B-S)%T=0,且S最小

    移项得 S=B%T

    即S是B对A的所有因子取模得到的数中最小的那个

    新的一次递归中,

    a ' =a,b ' =(B-S)*gcd(a,b),gcd ' = gcd*T

    如何得到T和S?

    枚举所有因子会TLE

    我们发现,整个过程a始终没有改变,只是参与了求gcd

    对于输入的a,b

    令A=a/gcd(a,b),B=b/gcd(a,b)

    这样A,B 就没有公因子

    这样 原来的b-S*gcd 相当于 现在的B-S

    求出A的所有素因子

    因为A为定值,所以下一次求S用A的素因子时,可以从上一次求S用的A的素因子剩下的里选

    就是说

    如果这次某个因子是B的因子,那么下一次就不会用这个因子了,B/=这个因子

    即这个因子参与构成新的gcd

    如果这次某个因子不是B的因子,下一次就可以考虑它

     

    #include<vector>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    LL ans;
    vector<LL>p;
    vector<LL> :: iterator it;
    LL gcd(LL a,LL b) { return !b ? a:gcd(b,a%b); }
    void work(LL y)
    {
        if(!y) return;
        LL k=y;
        for(it=p.begin();it!=p.end();++it) k=min(k,y%(*it));
        ans+=k; y-=k;
        vector<LL>q;
        for(it=p.begin();it!=p.end();++it)
         if(y%(*it)) q.push_back(*it);
         else y/=(*it);
        swap(p,q);
        work(y);
    }
    int main()
    {
        LL a,b;
        cin>>a>>b;
        LL g=gcd(a,b);
        a/=g; b/=g;
        for(LL i=2;i*i<=a;i++)
         while(a%i==0)
         {
             p.push_back(i);
             a/=i;
         }
        if(a>1) p.push_back(a);
        work(b); 
        cout<<ans;
    }
    E. Vasya's Function
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Vasya is studying number theory. He has denoted a function f(a, b) such that:

    • f(a, 0) = 0;
    • f(a, b) = 1 + f(a, b - gcd(a, b)), where gcd(a, b) is the greatest common divisor of a and b.

    Vasya has two numbers x and y, and he wants to calculate f(x, y). He tried to do it by himself, but found out that calculating this function the way he wants to do that might take very long time. So he decided to ask you to implement a program that will calculate this function swiftly.

    Input

    The first line contains two integer numbers x and y (1 ≤ x, y ≤ 1012).

    Output

    Print f(x, y).

    Examples
    input
    3 5
    output
    3
    input
    6 3
    output
    1
  • 相关阅读:
    excel中如何筛选出同一列有重复的数据
    JTextFile换行
    DOM事件对象用法
    js事件监听
    webstorm 破解方法
    vux使用
    vue动态添加当前事件下的class
    subline3 如何设置es6高亮
    vueJS+ES6开发移动端APP实战项目笔记
    css命名规范和书写规范
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7352791.html
Copyright © 2020-2023  润新知