E、幸运数字Ⅱ
解题思路
可以通过观察在一段区间内的值是相同的 1-3->4;4-6->7。
我们通过预处理将可能的值升序放在一个容器内,注意一点要把放进去,<-当输入1e9时。
给定l,r;我们通过lower_bound(it,it,l),查找l在容器中的位置。一步步往下去取区间,注意特判临界情况,即第一个区间的右边界>r,最后一个区间左边界是不是要全拿。
时间复杂度 O(N)
Code
#include <bits/stdc++.h> using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; inline int read() { int s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } const int maxn = 1e9 + 3; vector<ll> p; //存放4 7 44 47 74... queue<ll> que; void init() { p.push_back(4); p.push_back(7); que.push(4); que.push(7); while (que.size()) { ll x = que.front(); que.pop(); ll tmp1 = (x << 3) + (x << 1) + 4, tmp2 = (x << 3) + (x << 1) + 7; if (tmp1 < maxn) { p.push_back(tmp1); que.push(tmp1); } if (tmp2 < maxn) { p.push_back(tmp2); que.push(tmp2); } } p.push_back(4444444444); } int main() { init(); int l = read(), r = read(); int pos = lower_bound(p.begin(), p.end(), l) - p.begin(); ll sum = 0; if (p[pos] <= r) sum = (p[pos] - l + 1) * p[pos]; else { sum = (r - l + 1) * p[pos]; printf("%lld\n", sum); return 0; } for (++pos; p[pos] <= r; ++pos) sum += (p[pos] - p[pos - 1]) * p[pos]; if (p[pos] > r && p[pos - 1] != r) //r不在边界上 7777 sum += (r - p[pos - 1]) * p[pos]; printf("%lld\n", sum); return 0; }