BOJ 18830 하이퍼 수열과 하이퍼 쿼리

18830번: 하이퍼 수열과 하이퍼 쿼리

11차원이나 되어 복잡해 보이지만 1차원에서 2차원(나아가 2차원에서 3차원)으로 높이는 게 어려운 거지, 그 이후로 차원 늘리는 건 어려울 게 없다. DIM=11로 정의하고 반복, 재귀만으로 문제를 풀 수 있다.

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i = (a); i < (b); i++)
#define rep2(i,a,b) for(int i = (b) - 1; i >= (a); i--)
#define cinA(A, N) rep(i, 0, N) cin >> A[i];
#define coutA(A, N) rep(i, 0, N) cout << A[i] << " ";
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define pb push_back
#define eb emplace_back
#define em emplace
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define x first
#define y second
using namespace std;
using ll = int64_t;
using ull = uint64_t;
using ld = long double;
using pi = pair<int, int>;
using ti = tuple<int, int, int>;
using pl = pair<ll, ll>;
using tl = tuple<ll, ll, ll>;

const int DIM = 11, MAX = 1e6;
using arr = array<int, DIM>;
arr l, r, t;

int D[DIM], DM[DIM + 1], Q;
ll S[MAX];

istream& operator >> (istream& is, arr& A){
    rep(i, 0, DIM) is >> A[i];
    return is;
}
int main() {
    cin.tie(0) -> sync_with_stdio(false); cout.tie(0);
    rep(i, 0, DIM) cin >> D[i];
    DM[DIM] = 1;
    rep2(i, 0, DIM) DM[i] = DM[i + 1] * D[i];
    rep(i, 0, DM[0]) cin >> S[i];
    rep(i, 1, DIM + 1){
        rep(j, 0, DM[0] - DM[i]){
            if(j / DM[i - 1] == (j + DM[i]) / DM[i - 1]) S[j + DM[i]] += S[j];
        }
    }
    cin >> Q;
    function<ll(arr, int)> query = [&](arr A, int i){
        if(i == DIM){
            int p = 0;
            rep(k, 0, DIM){
                if(A[k] == -1) return (ll)0;
                p += A[k] * DM[k + 1];
            }
            return S[p];
        }
        ll ret = 0;
        A[i] = l[i] - 2;
        ret -= query(A, i + 1);
        A[i] = r[i] - 1;
        ret += query(A, i + 1);
        return ret;
    };
    while(Q --> 0){
        cin >> l >> r;
        cout << query(t, 0) << "\\n";
    }
}