Submission #1248051

#TimeUsernameProblemLanguageResultExecution timeMemory
1248051rythm_of_knightMinerals (JOI19_minerals)C++17
0 / 100
1 ms424 KiB
#include "minerals.h"
#include <bits/stdc++.h>
#define all(x) x.begin(), x.end()
using namespace std;

const int MXN = 43043, inf = 1e7;
vector <int> a, b;
static int cnt = 0, n, m;
int lg[MXN << 1], dp[MXN][2], mid[MXN][2];

int mid_find(int len) {
    int bg = 1;
    while (bg * 2 < len)
        bg <<= 1;
    return bg;
}

void rec(int l, int r, int k, vector <int> q) {
    if (l == r)
        return Answer(a[l], q[0]), void();
    int m = mid_find(r - l + 1), lk = k, rk = k;
    if (!k)
        m = l + m - 1;
    else
        m = r - m;
    m = mid[r - l + 1][k] + l;
    // cout << l << ' ' << r << ' ' << m << '\n' << flush;
    vector <int> lft, rgt;
    int lneed = m - l + 1, rneed = r - m;
    if (k) {
        for (int i = m + 1; i <= r; i++)
            cnt = Query(a[i]);
        rk ^= 1;
    } else {
        for (int i = l; i <= m; i++)
            cnt = Query(a[i]);
        lk ^= 1;
    }
    for (int j : q) {
        if (lft.size() == lneed) {
            rgt.push_back(j);
        } else if (rgt.size() == rneed) {
            lft.push_back(j);
        } else {
            int tmp = Query(j);
            if (tmp == cnt) {
                lft.push_back(j);
            } else {
                rgt.push_back(j);
            }
            cnt = tmp;
        }
    }
    rec(l, m, lk, lft);
    rec(m + 1, r, rk, rgt);
}

void Solve(int N) {
    n = N, m = 2 * n;
    lg[0] = -1;
    for (int i = 1; i <= m; i++)
        lg[i] = lg[i >> 1] + 1;
    for (int i = 1; i <= m; i++) {
        int tmp = Query(i);
        if (tmp != cnt)
            a.push_back(i);
        else
            b.push_back(i);
        cnt = tmp;
    }
    for (int i = 2; i <= n; i++) {
        dp[i][0] = dp[i][1] = inf;
        int md = i >> 1;
        int tl = max(0, md - 10000);
        int tr = min(i - 2, md + 10000);;
        for (int j = tl; j <= tr; j++) {
            if (dp[i][1] > dp[j + 1][1] + dp[i - j - 1][0] + i - j - 1) {
                dp[i][1] = dp[j + 1][1] + dp[i - j - 1][0] + i - j - 1;
                mid[i][1] = j;
            }
        }
        dp[i][1] += i - 1;
        for (int j = tl; j <= tr; j++) {
            if (dp[i][0] > dp[j + 1][1] + dp[i - j - 1][0] + j + 1) {
                dp[i][0] = dp[j + 1][1] + dp[i - j - 1][0] + j + 1;
                mid[i][0] = j;
            }
        }
        dp[i][0] += i - 1;
    }
    cout << dp[n][0] << ' ' << mid[n][0]  << '\n';
    rec(0, n - 1, 1, b);
}

/*
#include "minerals.h"
#include <bits/stdc++.h>
using namespace std;

const int N = 43e3 + 43;
int cards[N << 1], vis[N << 1], is[N << 1], knd[N], n, mx, cnt = 0;

void wa(int x) {
    cout << cnt << '\n';
    for (int i = 1; i <= 2 * n; i++)
        cout << cards[i] << ' ';
    cout << '\n';
    cout << "Wrong Answer[" << x << "]\n" << flush;
    exit(0);
}

void Answer(int a, int b) {
    // cout << a << ' ' << b << '\n';
    if (max(a, b) > 2 * n || min(a, b) < 1)
        wa(3);
    if (vis[a] || vis[b])
        wa(4);
    if (cards[a] != cards[b])
        wa(5);
    vis[a] = vis[b] = 1;
}

int res = 0;

int Query(int x) {
    if (x < 1 || x > 2 * n)
        wa(1);
    cnt++;
    if (cnt > mx)
        wa(2);
    res += knd[cards[x]] == 0;
    knd[cards[x]] -= is[x];
    is[x] ^= 1;
    knd[cards[x]] += is[x];
    res -= knd[cards[x]] == 0;
    return res;
}

mt19937 mt(chrono::high_resolution_clock().now().time_since_epoch().count());
int get(int l, int r) {
    return mt() % (r - l + 1) + l;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t = 1;
    // cin >> t;
    cin >> n;
    int worst = 0;
    while (t--) {
        cnt = res = 0;
        mx = 1e6;
        for (int i = 1; i <= 2 * n; i++) {
            int x = i + 1 >> 1;
            cards[i] = x;
            vis[i] = is[i] = 0, knd[i + 1 >> 1] = 0;
            swap(cards[i], cards[get(1, i)]);
        }
        Solve(n);
        worst = max(worst, cnt);
    }
    cout << "Accepted: " << worst << '\n';
}
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...