思路:
二分+数位dp
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL unsigned long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head LL dp[20][2][7]; int a[20]; LL dfs(int pos, bool limit, bool appear, int cnt) { if(pos == -1) { if(appear || cnt == 0) return 1; else return 0; } if(!limit && ~dp[pos][appear][cnt]) return dp[pos][appear][cnt]; int up = 9; if(limit) up = a[pos]; LL ans = 0; for (int i = 0; i <= up; i++) { ans += dfs(pos-1, limit&&i==up, appear||i==7, (cnt*10 + i) % 7); } if(!limit) dp[pos][appear][cnt] = ans; return ans; } LL solve(LL n) { if(n == 0) return 1; int cnt = 0; mem(dp, -1); while(n) { a[cnt++] = n % 10; n /= 10; } return dfs(cnt-1, 1, 0, 0); } int main() { LL n, m; scanf("%lld %lld", &m, &n); LL l = m+1, r = 1e18, mid = l+r >> 1; LL sub = solve(m); while(l < r) { if(solve(mid) - sub >= n) r = mid; else l = mid + 1; mid = l+r >> 1; } printf("%lld ", mid); return 0; }