제출 #1368464

#제출 시각아이디문제언어결과실행 시간메모리
1368464dashkaSequence (BOI23_sequence)C++20
100 / 100
183 ms23552 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll inf = 1e18;

typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll, ll> p2;

#define rep(i, high) for (ll i = 0; i < (high); i++)
#define repp(i, lo, high) for (ll i = (lo); i < (high); i++)
#define repe(i, container) for (auto& i : container)
#define sz(x) ((ll)(x).size())
#define all(x) begin(x), end(x)

vi w;
vvi divisors;
unordered_map<ll, ll> dp;

ll comp_hash(set<ll>&x)
{
    ll ret = 1;
    repe(v, x)
    {
        ret = (ret + v) * 12423457;
    }

    return ret;
}

ll best(set<ll>& state)
{
    if (state.empty()||(sz(state)==1&&*begin(state)==1))
    {
        return 0;
    }

    auto it = dp.find(comp_hash(state));
    if (it != dp.end()) return it->second;

    ll ret = inf;
    ll v = *prev(end(state));

    {
        bool in = state.count(v - 1);
        ll extra = in ? 0 : w[v - 1];
        state.insert(v - 1);
        state.erase(v);
        ret = min(ret, extra+best(state));
        state.insert(v);
        if (!in) state.erase(v - 1);
    }

    repe(d, divisors[v])
    {
        bool din = state.count(d);
        bool vd_in = state.count(v / d);
        ll extra = din ? 0 : w[d];
        if (!vd_in && v/d!=d) extra += w[v / d];
        state.insert(d);
        state.insert(v/d);
        state.erase(v);
        ret = min(ret, extra + best(state));
        state.insert(v);
        if (!din) state.erase(d);
        if (!vd_in) state.erase(v / d);
    }

    return dp[comp_hash(state)]=ret;
}


int main()
{
    cin.tie(0)->sync_with_stdio(0);
    
    dp.reserve(int(1e6));

    ll n;
    cin >> n;
    w.resize(n);
    repe(v, w) cin >> v;
    w.insert(w.begin(), 0LL);
    divisors.resize(n + 1);

    repp(i, 1, n + 1)
    {
        vi divs;
        ll j = 2;
        ll v = i;
        while (v>1&&j*j<=v)
        {
            if (v % j == 0) divs.push_back(j);
            j++;
        }
        divisors[i] = divs;
    }

    repp(i, 1, n+1)
    {
        set<ll> st = { i };
        cout << best(st)+w[i] << "\n";
    }

    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…