cf837E(xjb)
题目链接:http://codeforces.com/problemset/problem/837/E
题意:f(a, 0) = 0 ,
f(a, b) = 1 + f(a, b - gcd(a, b))
给出 a, b,求 f(a, b).
思路:对于当前 a, b,若 gcd(a, b) = c,那么 b = k * c, b 每次减少 c 直到 gcd(a, b) != c, 即 k 每次减小 1, 直至 k 与 a 存在其他因子 d, 即:gcd(a', b') = d, 那么 b' = k' * d.当前对答案的贡献则为 k - k', 依次类推下去即可.
代码:
1 #include <iostream> 2 #include <math.h> 3 #define ll long long 4 using namespace std; 5 6 const ll inf = 0x3f3f3f3f3f3f3f3f; 7 8 ll gcd(ll a, ll b){ 9 return b == 0 ? a : gcd(b, a % b); 10 } 11 12 int main(void){ 13 ll x, y, sol = 0; 14 cin >> x >> y; 15 while(y >= 1){ 16 ll gg = gcd(x, y); 17 y /= gg; 18 x /= gg; //注意x中的因子gg也要去掉,不然会影响后面步骤 19 ll cnt = inf, gel = x; 20 for(ll i = 2; i * i <= gel; i++){//将当前x质因分解并找出y模x的质因子中最小值作为当前轮对答案的贡献 21 if(gel % i == 0){ 22 cnt = min(cnt, y % i); 23 while(gel % i == 0){ 24 gel /= i; 25 } 26 } 27 } 28 if(gel > 1) cnt = min(cnt, y % gel); 29 sol += cnt; 30 y -= cnt; 31 } 32 cout << sol + y << endl; 33 return 0; 34 }
我就是我,颜色不一样的烟火 --- geloutingyu