Submission #638615

#TimeUsernameProblemLanguageResultExecution timeMemory
638615maomao90Prisoner Challenge (IOI22_prison)C++17
100 / 100
80 ms1400 KiB
// Hallelujah, praise the one who set me free
// Hallelujah, death has lost its grip on me
// You have broken every chain, There's salvation in your name
// Jesus Christ, my living hope
#include <bits/stdc++.h>
#include "prison.h"
using namespace std;

#define REP(i, s, e) for (int i = (s); i < (e); i++)
#define RREP(i, s, e) for (int i = (s); i >= (e); i--)
template <class T>
inline bool mnto(T& a, T b) {return a > b ? a = b, 1 : 0;}
template <class T>
inline bool mxto(T& a, T b) {return a < b ? a = b, 1: 0;}
typedef long long ll;
typedef long double ld;
#define FI first
#define SE second
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef tuple<int, int, int> iii;
#define ALL(_a) _a.begin(), _a.end()
#define SZ(_a) (int) _a.size()
#define pb push_back
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<ii> vii;
typedef vector<iii> viii;

#ifndef DEBUG
#define cerr if (0) cerr
#endif

const int INF = 1000000005;
const ll LINF = 1000000000000000005ll;
const int MAXN = 5005;

int n;
vector<vi> ans;
vector<vi> nans;
int sp[MAXN], dp[MAXN], nxt[MAXN];

void solve(int c, int clo, int chi, int lo, int hi, int cp, int len) {
    ans[c][0] = cp;
    REP (i, lo, clo) {
	ans[c][i] = -cp - 1;
    }
    REP (i, chi + 1, hi + 1) {
	ans[c][i] = -(cp ^ 1) - 1;
    }
    if (chi - clo <= 1) {
	ans[c][clo] = -cp - 1; ans[c][chi] = -(cp ^ 1) - 1;
	return;
    }
    int need = (len - 3) / sp[len] + 1;
    ans[c][clo] = -cp - 1; ans[c][chi] = -(cp ^ 1) - 1;
    int nlo = clo + 1;
    REP (i, nxt[c], nxt[c] + need) {
	int nhi = min(chi - 1, nlo + sp[len] - 1);
	REP (j, nlo, nhi + 1) {
	    ans[c][j] = i;
	}
	ans[i][clo] = -(cp ^ 1) - 1; ans[i][chi] = -cp - 1;
	solve(i, nlo, nhi, clo + 1, chi - 1, cp ^ 1, sp[len]);
	nlo = nhi + 1;
    }
}

vector<vi> devise_strategy(int n) {
    ::n = n;
    if (n == 2) {
	ans.resize(1, vi(3, 0));
	ans[0][1] = -1; ans[0][2] = -2;
	return ans;
    }
    REP (i, 0, 3) {
	dp[i] = 0;
	sp[i] = i;
    }
    REP (i, 3, n + 1) {
	dp[i] = i;
	int ptr = 0;
	REP (j, 0, i) {
	    while (ptr < i && dp[ptr] <= j) {
		ptr++;
	    }
	    int need = (i - 3) / (ptr - 1) + 1;
	    if (mnto(dp[i], j + need)) {
		sp[i] = ptr - 1;
	    }
	}
	cerr << i << ": " << dp[i] << ' ' << sp[i] << '\n';
    }
    nxt[0] = 1;
    int tmp = 1;
    int tn = n;
    while (tn >= 3) {
	int need = (tn - 3) / sp[tn] + 1;
	REP (i, tmp, tmp + need) {
	    nxt[i] = tmp + need;
	}
	tmp += need;
	tn = sp[tn];
    }
    ans = vector<vi>(tmp, vi(n + 1, 0));
    ans[0][0] = 0; ans[0][1] = -1; ans[0][n] = -2;
    int need = (n - 3) / sp[n] + 1; 
    int lo = 2;
    REP (i, 1, 1 + need) {
	int hi = min(n - 1, lo + sp[n] - 1);
	REP (j, lo, hi + 1) {
	    ans[0][j] = i;
	}
	ans[i][1] = -2; ans[i][n] = -1;
	solve(i, lo, hi, 2, n - 1, 1, sp[n]);
	lo = hi + 1;
    }
    cerr << SZ(ans) - 1 << '\n';
    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...