문제 링크

을 다 계산하면 큰일난다. 초가 지났을 때 번째 숫자, 그리고 번째까지 의 개수라고 정의하자. 이는 을 통해 알아낼 수 있다.

#include <bits/stdc++.h>
 
using namespace std;
using ll = long long;
 
int S, L, R, N;
 
vector<int> vectors[4] = {{}, {1, 3, 2}, {2, 1, 1}, {2, 3, 2}};
 
vector<int>& getvec(int num) {
    return vectors[num];
}
 
vector<int> solve(int n, int k) {
    // ret[0] -> k번째 숫자
    // ret[1] ~ ret[3] -> n번 진행했을 때 k번째까지 1, 2, 3의 개수
    vector<int> ret(4);
 
    if (n == 0) {
        ret[0] = S;
        ret[S] = 1;
        return ret;
    }
 
    vector<int> tmp = solve(n - 1, k / 3);
    int ln = tmp[0];
    vector<int>& v = getvec(ln);
 
    if (k % 3 == 0) {
        ret[0] = v[0];
        ret[v[0]]++;
        tmp[ln]--;
    }
    else if (k % 3 == 1) {
        ret[0] = v[1];
        ret[v[0]]++;
        ret[v[1]]++;
        tmp[ln]--;
    }
    else {
        ret[0] = v[2];
    }
 
    ret[1] += tmp[1] + tmp[2]*2;
    ret[2] += tmp[1] + tmp[2] + tmp[3]*2;
    ret[3] += tmp[1] + tmp[3];
 
    return ret;
}
 
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
 
    cin >> S >> L >> R >> N;
 
    vector<int> v1 = solve(N, R);
    vector<int> v2;
    if (L == 0) v2 = {0, 0, 0, 0};
    else v2 = solve(N, L-1);
 
    cout << v1[1] - v2[1] << ' ' << v1[2] - v2[2] << ' ' << v1[3] - v2[3] << '\n';
 
    return 0;
}