59022023-10-05 00:25:57TuruTamasSzivárványszámokcpp17Wrong answer 18/45214ms63236 KiB
#include "bits/stdc++.h"
#include <cassert>
#include <climits>
#include <cstddef>
#include <set>
#include <string>
#include <type_traits>
#include <vector>
using namespace std;

#define ll unsigned long long

string s;
ll r = 0;
int init_size;
vector<vector<vector<vector<ll>>>> v;
string cur;
set<string> hs;
set<tuple<string, bool, bool, int, int, size_t>> hs2;

void recurse(bool past_mid, bool any, int lastval, int index) {
    if (index != 0) cur.push_back(lastval + '0');
    if (index == s.size()) {
        assert(!hs.count(cur));
        hs.emplace(cur);
        r += s.size() == init_size ? any : 1;
        char last = '0';
        int i;
        bool f = false;
        // cout << s << " " << cur << endl;
        for (i = 0; i < cur.size(); i++) {
            last = cur[i];
            if (!f && cur[i] < s[i])
                f = true;
            assert(f || cur[i] <= s[i] || init_size > cur.size());
            if (cur[i] < last)
                break;
        }
        for (; i < cur.size(); i++) {
            if (!f && cur[i] < s[i])
                f = true;
            assert(f || cur[i] <= s[i] || init_size > cur.size());
            assert(cur[i] <= last);
            last = cur[i];
        }
        cur.pop_back();
        return;
    }
    ll& val = v[past_mid][any][lastval][index];
    if (val != -1) {
        r += val;
        // cout << "dbg: " << cur << ", " << past_mid << " " << any << " " << lastval << " " << index << endl;
        assert(!hs2.count({cur, past_mid, any, lastval, index, s.size()}));
        hs2.insert({cur, past_mid, any, lastval, index, s.size()});
        cur.pop_back();
        return;
    }
    int old_val = r;
    if (any) {
        int mini = index == 0 ? 1 : 0;
        for (int i = mini; i <= 9; i++) {
            if (!past_mid && i >= lastval)
                recurse(false, true, i, index+1);
            else if (!past_mid && i < lastval)
                recurse(true, true, i, index+1);
            else if (past_mid && i <= lastval)
                recurse(true, true, i, index+1);
        }
    }
    else {
        int maxval = s[index] - '0';
        // cout << maxval << endl;
        if (past_mid && maxval <= lastval)
            recurse(true, false, maxval, index+1);
        else if (!past_mid)
            recurse(maxval < lastval, false, maxval, index+1);
        
        int mini = index == 0 ? 1 : 0;
        int maxi = min(past_mid ? lastval : 9, maxval-1);
        for (int i = mini; i <= maxi; i++)
            recurse(past_mid || i < lastval, true, i, index+1);
    }
    val = r-old_val;
    if (index != 0) cur.pop_back();
}

int main() {
    cin >> s;
    init_size = s.size();
    v.assign(2, vector<vector<vector<ll>>>(2, vector<vector<ll>>(10, vector<ll>(s.size(), -1))));
    recurse(false, false, 0, 0);
    s.pop_back();
    while (!s.empty()) {
        v.clear();
        v.assign(2, vector<vector<vector<ll>>>(2, vector<vector<ll>>(10, vector<ll>(s.size(), -1))));
        recurse(false, true, 0, 0);
        s.pop_back();
    }
    cout << r + 1 << endl;
}
SubtaskSumTestVerdictTimeMemory
base18/45
1Accepted0/03ms1848 KiB
2Accepted0/04ms2724 KiB
3Wrong answer0/0159ms42932 KiB
4Accepted1/13ms2408 KiB
5Accepted1/13ms2648 KiB
6Accepted1/13ms3028 KiB
7Accepted1/13ms3252 KiB
8Accepted1/13ms3188 KiB
9Accepted1/13ms3188 KiB
10Accepted1/13ms3468 KiB
11Accepted1/13ms3584 KiB
12Accepted1/13ms3588 KiB
13Accepted2/24ms3864 KiB
14Accepted2/24ms3948 KiB
15Accepted2/24ms4076 KiB
16Accepted2/24ms4296 KiB
17Accepted1/14ms4380 KiB
18Wrong answer0/282ms26068 KiB
19Wrong answer0/2131ms38268 KiB
20Runtime error0/2206ms63236 KiB
21Runtime error0/3194ms63000 KiB
22Wrong answer0/214ms7356 KiB
23Wrong answer0/213ms7072 KiB
24Wrong answer0/214ms7396 KiB
25Runtime error0/2214ms62972 KiB
26Runtime error0/2208ms62964 KiB
27Runtime error0/2207ms62940 KiB
28Runtime error0/2202ms62924 KiB
29Runtime error0/2199ms62916 KiB
30Runtime error0/2200ms62684 KiB