Codeforces 251C Number Transformation
我们能发现这个东西是以2 - k的lcm作为一个循环节, 然后bfs就好啦。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 5e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); LL a, b; int k, lcm = 1; int dp[N]; void getDp(int x) { memset(dp, -1, sizeof(dp)); dp[x] = 0; queue<int> que; que.push(x); while(!que.empty()) { int u = que.front(); que.pop(); if(dp[u - 1] == -1) { dp[u - 1] = dp[u] + 1; que.push(u - 1); } for(int i = 2; i <= k; i++) { int v = u - (u % i); if(~dp[v]) continue; dp[v] = dp[u] + 1; que.push(v); } } } int main() { scanf("%lld%lld%d", &a, &b, &k); swap(a, b); for(int i = 2; i <= k; i++) lcm = lcm / __gcd(lcm, i) * i; LL ans = 0; LL R = b - (b % lcm); LL L = a + (lcm - a % lcm) % lcm; if(L <= R) { LL cnt = (R - L) / lcm; getDp(lcm - 1); ans = dp[0] * cnt + cnt; if(a % lcm) ans += dp[a % lcm] + 1; getDp(b % lcm); ans += dp[0]; } else { getDp(b % lcm); ans = dp[a % lcm]; } printf("%lld\n", ans); return 0; } /* */