제출 #1354061

#제출 시각아이디문제언어결과실행 시간메모리
1354061toast12코끼리 (Dancing Elephants) (IOI11_elephants)C++20
10 / 100
0 ms344 KiB
#include <bits/stdc++.h>
using namespace std;

int n, l;
int sqrtn;
vector<vector<int>> blocks;
vector<vector<int>> ids;
vector<vector<pair<int, int>>> dp;
vector<pair<int, int>> loc; // block no., position in the block

void calc(int i) {
    for (int j = blocks[i].size()-1; j >= 0; j--) {
        dp[i][j] = {1, blocks[i][j]+l};
        auto it = upper_bound(blocks[i].begin(), blocks[i].end(), blocks[i][j]+l);
        if (it != blocks[i].end()) {
            int idx = it-blocks[i].begin();
            dp[i][j].first += dp[i][idx].first;
            dp[i][j].second = dp[i][idx].second;
        }
    }
}

void init(int N, int L, int X[]) {
    n = N;
    l = L;
    loc.resize(n);
    sqrtn = (int)sqrt(n);
    if (n == 2) blocks.resize(2);
    else blocks.resize(sqrtn);
    ids.resize(blocks.size());
    for (int i = 0, idx = 0; i < n; i += sqrtn, idx++) {
        for (int j = i; j < min(n, i+sqrtn); j++) {
            blocks[idx].push_back(X[j]);
            ids[idx].push_back(j);
            loc[j] = {idx, j-i};
        }
    }
    dp.resize(blocks.size());
    for (int i = 0; i < sqrtn; i++) {
        dp[i].resize(blocks[i].size());
        calc(i);
    }
    if (sqrtn == 1) sqrtn = n;
}

void remove(int i) {
    int b = loc[i].first, x = loc[i].second;
    // remove this elephant from its current block
    blocks[b].erase(blocks[b].begin()+x);
    ids[b].erase(ids[b].begin()+x);
    // renumber all the elephants from this block
    for (int j = 0; j < blocks[b].size(); j++) loc[ids[b][j]] = {b, j};
}

void add(int val, int i, int nxt) {
    vector<int> new_block, new_ids;
    bool done = false;
    for (int j = 0; j < blocks[nxt].size(); j++) {
        if (!done && blocks[nxt][j] > val) {
            new_block.push_back(val);
            new_ids.push_back(i);
            loc[i] = {nxt, j};
            done = true;
        }
        new_block.push_back(blocks[nxt][j]);
        new_ids.push_back(ids[nxt][j]);
        loc[ids[nxt][j]] = {nxt, j};
        if (done) loc[ids[nxt][j]].second++;
    }
    if (!done) {
        new_block.push_back(val);
        new_ids.push_back(i);
        loc[i] = {nxt, new_block.size()-1};
    }
    blocks[nxt] = new_block;
    ids[nxt] = new_ids;
}

int update(int i, int y) {
    int cur = loc[i].first;
    remove(i);
    bool added = false;
    int nxt = sqrtn-1;
    for (int j = 0; j < sqrtn; j++) {
        if (y <= blocks[j].back()) {
            add(y, i, j);
            added = true;
            nxt = j;
            break;
        }
    }
    if (!added) add(y, i, sqrtn-1);
    dp[cur].resize(blocks[cur].size());
    calc(cur);
    dp[nxt].resize(blocks[nxt].size());
    calc(nxt);
    int ans = 0;
    for (int j = 0, k = 0; j < sqrtn;) {
        if (dp[j].empty()) {
            j++;
            continue;
        }
        ans += dp[j][k].first;
        int last = dp[j][k].second;
        j++;
        while (j < sqrtn) {
            auto it = upper_bound(blocks[j].begin(), blocks[j].end(), last);
            if (it == blocks[j].end()) j++;
            else {
                k = it-blocks[j].begin();
                break;
            }
        }
    }
    return ans;
}
#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...