UOJ Logo

NOI.AC

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#211723#2909. numberLZDQ20946ms13736kbC++2.4kb2024-09-13 11:02:502024-09-13 11:02:52

answer

#include <iostream>
#include <vector>
#include <cmath>
#include <string>

using namespace std;

typedef long long ll;
const int MAX_Y = 1e5 + 1000; // Maximum value of y plus buffer
const int MAX_K = 20;         // Since 2^20 > 1e5, this is sufficient
const int INF = 1e9 + 7;

int sum_of_digits(int x) {
    int sum = 0;
    while (x > 0) {
        sum += x % 10;
        x /= 10;
    }
    return sum;
}

int main() {
    ios::sync_with_stdio(false);
    // cin.tie(nullptr);

    int q;
    cin >> q;
    vector<pair<int, int> > queries(q);
    int max_y = 0;
    for (int i = 0; i < q; ++i) {
        int x, y;
        cin >> x >> y;
        queries[i] = {x, y};
        max_y = max(max_y, y);
    }
    max_y = min(max_y, (int)1e5); // Ensure y ≤ 1e5

    int MAX_X = max_y + 1000; // Slight buffer
    vector<int> s(MAX_X + 1, 0);
    vector<vector<int> > next(MAX_K, vector<int>(MAX_X + 1, INF));

    // Precompute sum of digits
    for (int x = 1; x <= MAX_X; ++x) {
        s[x] = s[x / 10] + x % 10;
    }

    // Compute next[0][x] = x + s(x)
    for (int x = 1; x <= MAX_X; ++x) {
        int nx = x + s[x];
        if (nx <= MAX_X) {
            next[0][x] = nx;
        } else {
            next[0][x] = INF;
        }
    }

    // Build jump table
    for (int k = 1; k < MAX_K; ++k) {
        for (int x = 1; x <= MAX_X; ++x) {
            int nx = next[k - 1][x];
            if (nx <= MAX_X) {
                next[k][x] = next[k - 1][nx];
            } else {
                next[k][x] = INF;
            }
        }
    }

    // Answer queries
    for (int i = 0; i < q; ++i) {
        int x = queries[i].first;
        int y = queries[i].second;
        if (x > MAX_X) {
            // x is beyond precomputed range
            // Simulate steps until x > y
            while (x <= y) {
                int curr_s = sum_of_digits(x);
                x += curr_s;
            }
            cout << x << '\n';
            continue;
        }
        int curr_x = x;
        // Binary lifting
        for (int k = MAX_K - 1; k >= 0; --k) {
            if (next[k][curr_x] <= y) {
                curr_x = next[k][curr_x];
            }
        }
        // After jumps, simulate the remaining steps
        while (curr_x <= y) {
            curr_x += s[curr_x];
        }
        cout << curr_x << '\n';
    }

    return 0;
}

详细

小提示:点击横条可展开更详细的信息

Subtask #1:

score: 20
Accepted

Test #1:

score: 20
Accepted
time: 598ms
memory: 13736kb

input:

500000
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20
1 ...

output:

2
4
4
8
8
8
8
16
16
16
16
16
16
16
16
23
23
23
23
23
23
23
28
28
28
28
28
38
38
38
38
38
38
38
38
38...

result:

ok 500000 lines

Test #2:

score: 0
Accepted
time: 348ms
memory: 13732kb

input:

500000
92 99927
119 99453
481 99268
29 99908
267 99547
835 99500
955 99099
734 99774
306 99883
729 9...

output:

99941
99454
99274
99941
99555
99520
99112
99775
99900
99657
99978
100010
99545
99245
99775
99907
997...

result:

ok 500000 lines

Subtask #2:

score: 0
Time Limit Exceeded

Test #3:

score: 0
Time Limit Exceeded

input:

500000
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20
1 ...

output:

2
4
4
8
8
8
8
16
16
16
16
16
16
16
16
23
23
23
23
23
23
23
28
28
28
28
28
38
38
38
38
38
38
38
38
38...

result:


Subtask #3:

score: 0
Wrong Answer

Test #4:

score: 0
Wrong Answer
time: 0ms
memory: 1356kb

input:

50
4587480273 4587480273
428862505 500400481
6920415626 7358620174
7787875953 7787884613
4542304779 ...

output:

2147483647
2147483647
2147483647
2147483647
2147483647
2147483647
2147483647
2147483647
2147483647
2...

result:

wrong answer 1st lines differ - expected: '4587480321', found: '2147483647'

Subtask #4:

score: 0
Skipped