Codeforces 837E. Vasya's Function

http://codeforces.com/problemset/problem/837/E

题意:

  • 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

Codeforces 837E. Vasya's Function

原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7352791.html

时间: 2024-08-29 12:45:27

Codeforces 837E. Vasya's Function的相关文章

CodeForces - 837E - Vasya&#39;s Function | Educational Codeforces Round 26

/* CodeForces - 837E - Vasya's Function [ 数论 ] | Educational Codeforces Round 26 题意: f(a, 0) = 0; f(a, b) = 1 + f(a, b-gcd(a, b)); 求 f(a, b) , a,b <= 1e12 分析: b 每次减 gcd(a, b) 等价于 b/gcd(a,b) 每次减 1 减到什么时候呢,就是 b/gcd(a,b)-k 后 不与 a 互质 可先将 a 质因数分解,b能除就除,不能

Codeforces 837E Vasya&#39;s Function 数论 找规律

题意:定义F(a,0) = 0,F(a,b) = 1 + F(a,b - GCD(a,b).给定 x 和 y (<=1e12)求F(x,y). 题解:a=A*GCD(a,b) b=B*GCD(a,b),那么b-GCD(a,b) = (B-1)*GCD(a,b),如果此时A和B-1依然互质,那么GCD不变下一次还是要执行b-GCD(a,b).那么GCD什么时候才会变化呢?就是说找到一个最小的S,使得(B-S)%T=0其中T是a的任意一个因子.变形得到:B%T=S于是我们知道S=min(B%T).也

Codeforces 837E Vasya&#39;s Function - 数论

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).

Educational Codeforces Round 26 E - Vasya&#39;s Function

数论题还是好恶心啊. 题目大意:给你两个不超过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

Ural 1353 Milliard Vasya&#39;s Function(DP)

题目地址:Ural 1353 定义dp[i][j],表示当前位数为i位时,各位数和为j的个数. 对于第i位数来说,总可以看成在前i-1位后面加上一个0~9,所以状态转移方程就很容易出来了: dp[i][j]=dp[i][j]+dp[i][j-1]+dp[i][j-2]+.......+dp[i][j-9]: 最后统计即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <

CodeForces 577C Vasya and Petya&#39;s Game 数学

题意就是给你一个1到n的范围 你每次可以问这个数是否可以被某一个数整除 问你要猜多少数才能确定这个数…… 一开始一点思路也没有 后来查了一下才知道 每个数都可以分为几个质数的整数次幂相乘得到…… 1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<math.h> 5 #include<string.h> 6 #include<string>

URAL1353---Milliard Vasya&#39;s Function(简单数位dp)

Vasya is the beginning mathematician. He decided to make an important contribution to the science and to become famous all over the world. But how can he do that if the most interesting facts such as Pythagor's theorem are already proved? Correct! He

timus.1353. Milliard Vasya&#39;s Function 动态规划

题目传送门 题目大意: 输入一个1到81(9*9)的数字s,求在1到109有多少个数字的数位和等于s. 解题思路: 我们很容易知道一位数字等于s的个数.要使一个i位的数字数位和等于s,可以通过一个i-1位的数字后面加上0~9(如果s<9就是0~s).于是很容易得出方程 dp[i][j]=dp[i-1][j-0]+dp[i-2][j-1]+……+dp[i-9][j-9];其中i表示i位的数字,j表示s.dp[i][j]表示一个i位数字数位和为j的方案数. #include <iostream&g

递推DP URAL 1353 Milliard Vasya&#39;s Function

题目传送门 1 /* 2 题意:1~1e9的数字里,各个位数数字相加和为s的个数 3 递推DP:dp[i][j] 表示i位数字,当前数字和为j的个数 4 状态转移方程:dp[i][j] += dp[i-1][j-k],为了不出现负数 5 改为:dp[i][j+k] += dp[i-1][j] 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <cmath> 10 #include <algorithm