Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <map>
- #include <cmath>
- #include <ctime>
- using namespace std;
- typedef long long Integer;
- const Integer LIMIT = 6350;
- Integer K, A, B;
- int P, Q, k;
- map<Integer, Integer> *cache[12][100];
- inline void clear(){ for (int i = 0 ; i < 12; ++i) for (int j = 0; j < 100; ++j) for (int s = 0; s < k; ++s) cache[i][j][s].clear(); }
- inline int MAX(int a, int b) { return a >b ? a : b; }
- inline int MIN(int a, int b) { return a < b ? a : b; }
- inline int ssss(Integer a) {int total = 0;while(a) { total += a % 10; a /= 10; } return total; }
- inline int length1(Integer a) { int total = 0; while (a) { ++total; a /= 10; } return total; }
- Integer POWERS[15];
- inline Integer doIt(int length, int sum, int r, Integer u) {
- if (length == 1) {
- return (long long)sum <= u && (sum + r) % k == 0;
- }
- if (cache[length][sum][r].count(u) ) {
- return cache[length][sum][r][u];
- }
- int prevSum = MAX( MAX(sum - 9, 0), sum - (int) (u / POWERS[length - 1]));
- Integer result = 0;
- result += doIt(length - 1, prevSum, ( POWERS[length - 1] * (sum - prevSum) + r) % k, u % POWERS[length - 1]);
- int maxSum = MIN((length - 1) * 9, sum);
- ++prevSum;
- for (; prevSum <= maxSum; ++prevSum) {
- result += doIt(length - 1, prevSum, (POWERS[length - 1] * (sum - prevSum) + r ) % k, POWERS[length - 1] - 1);
- }
- return cache[length][sum][r][u] = result;
- }
- inline Integer go(Integer to) {
- clear();
- int length = length1(to);
- Integer result = 0;
- int upper = MIN(9 * length, Q);
- for (; upper >= P; --upper) result += doIt(length, upper, 0, to);
- return result;
- }
- inline Integer triv() {
- Integer starter = (A - 1) / K + 1;
- starter *= K;
- Integer result = 0;
- for (; starter <= B; starter += K) {
- int now = ssss(starter);
- result += now >= P && now <= Q;
- }
- return result;
- }
- int main() {
- freopen("lucky.in", "r", stdin);
- freopen("lucky.out", "w", stdout);
- cin >> K >> P >> Q >> A >> B;
- Integer lim = (Integer)sqrt(B + .0);
- if (K > lim / 50) {
- cout << triv();
- return 0;
- }
- POWERS[0] = 1;
- //for (int i = 0; i < M; i++) digsum[i] = i % 10 + digsum[i / 10];
- for (int i = 1; i < 15; ++i) POWERS[i] = POWERS[i - 1] * 10;
- k = (int) K;
- for (int i = 0; i < 12; ++i) for (int j = 0; j < 100; ++j) { cache[i][j] = new map<Integer, Integer> [k]; }
- cout << (go(B) - go(A - 1));
- return 0;
- }
Add Comment
Please, Sign In to add comment