제출 #1128041

#제출 시각아이디문제언어결과실행 시간메모리
1128041Mike_VuDancing Elephants (IOI11_elephants)C++17
100 / 100
3312 ms6476 KiB
///problem: https://oj.uz/problem/view/IOI11_elephants
#ifndef mikevui
//    #include "task.h"
#endif // mikevui

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double dou;
#define pii pair<int, int>
#define fi first
#define se second
#define pb push_back
#define MASK(x) (1LL<<(x))
#define BITj(x, j) (((x)>>(j))&1)
#define ALL(v) (v).begin(), (v).end()

template<typename T> bool maximize(T &x, const T &y) {
    if (x < y) {x = y; return 1;}
    return 0;
}
template<typename T> bool minimize(T &x, const T &y) {
    if (x > y) {x = y; return 1;}
    return 0;
}

const int B = 522; //B=522
int cntqu = 0;

int n, len;
vector<int> a, trackid;
vector<vector<int>> blocks;
vector<vector<pii>> dp; //{cost, range}

void builddp(vector<int> &a, vector<pii> &dp) {
    int sz = a.size();
    dp.assign(sz, {0, 0});
    int j = sz;
    for (int i= sz-1; i >= 0; i--) {
        while (a[i]+len < a[j-1]) --j;
        if (j == sz) {
            dp[i] = {1, a[i]+len};
        }
        else {
            dp[i] = {dp[j].fi+1, dp[j].se};
        }
    }
}
void buildblocks() {
    blocks.clear();
    dp.clear();
    for (int i= 0; i < n; i+=B) {
        blocks.pb(vector<int>());
        dp.pb(vector<pii>());
        for (int j = i; j < min(i+B, n); j++) {
            blocks.back().pb(a[j]);
        }
        builddp(blocks.back(), dp.back());
    }
}
void rebuildarr() {
    a.clear();
    for (int i= 0; i < (int)blocks.size(); i++) {
        for (int pos : blocks[i]) {
            a.pb(pos);
        }
    }
}

void init(int N, int L, int X[]) {
    n = N;
    len = L;
    a.assign(n, 0);
    trackid.assign(n, 0);
    for (int i= 0; i < n; i++) {
        a[i] = trackid[i] = X[i];
    }
    buildblocks();
//    for (int i = 0; i < (int)blocks.size(); i++) {
//        for (int pos : blocks[i]) {
//            cout << pos << ' ';
//        }
//        cout << "\n";
//    }
}
//init
//build blocks
//build dp over each blocks

void remval(int pos) {
    int j = 0;
//    cout << pos << endl;
//    system("pause");
    while (blocks[j].back() < pos) {
//        cout << blocks[j].back() << endl;
//        system("pause");
        ++j;
    }
//    system("pause");
    vector<int> newbl;
    bool met = 0;
    for (int i= 0; i < (int)blocks[j].size(); i++) {
        if (blocks[j][i] == pos && !met) {
            met = 1;
            continue;
        }
        newbl.pb(blocks[j][i]);
    }
    swap(newbl, blocks[j]);
    builddp(blocks[j], dp[j]);
//    for (int p : blocks[j]) {
//        cout << p << ' ';
//    }
//    cout << "\n";
}
void insval(int pos) {
    int j = 0;
    while (j+1 < (int)blocks.size() && blocks[j].back() < pos) ++j;
    vector<int> newbl;
    bool met = 0;
    for (int i= 0; i < (int)blocks[j].size(); i++) {
        if (!met && (i > 0 && (blocks[j][i] >= pos && blocks[j][i-1] <= pos))) {
            met = 1;
            newbl.pb(pos);
        }
        if (!met && (i == 0 && blocks[j][i] >= pos)) {
            met = 1;
            newbl.pb(pos);
        }
        newbl.pb(blocks[j][i]);
    }
    if (!met) newbl.pb(pos);
    swap(newbl, blocks[j]);
    builddp(blocks[j], dp[j]);
//    for (int p : blocks[j]) {
//        cout << p << ' ';
//    }
//    cout << "\n";
}

int query() {
    int las = -1, res = 0;
    for (int i= 0; i < (int)blocks.size(); i++) {
        if (blocks[i].empty() || las >= blocks[i].back()) continue;
        //binsearch
        int k = (int)blocks[i].size()-1;
        for (int j = (k+1)>>1; j; j >>= 1) {
            while (k-j >= 0 && blocks[i][k-j] > las) k -= j;
        }
        res += dp[i][k].fi;
        las = dp[i][k].se;
    }
    return res;
}

int update(int id, int pos) {
    //rebuild
    //rebuild arr
    //build blocks + dp over each blocks
    ++cntqu;
    if (cntqu%(B-1) == 0) {
        rebuildarr();
        buildblocks();
    }
//    system("pause");
    //updates:
    //remove
    remval(trackid[id]);
//    system("pause");
    //insert
    insval(pos);
    //rebuild dp of block
    trackid[id] = pos;
//    for (int i = 0; i < (int)blocks.size(); i++) {
//        for (int pos : blocks[i]) {
//            cout << pos << ' ';
//        }
//        cout << endl;
//    }
//    system("pause");
    //queries:
    //binsearch for each block
    return query();
}

#ifdef mikevui
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
//    #define name "task"
//    if (fopen(name".inp", "r")) {
//        freopen(name".inp", "r", stdin);
//        freopen(name".out", "w", stdout);
//    }
    int N, L, X[(int)1e5];
    cin >> N >> L;
    for (int i= 0; i < N; i++) {
        cin >> X[i];
    }
    init(N, L, X);
    int Q;
    cin >> Q;
    while (Q--) {
        int I, Y;
        cin >> I >> Y;
        cout << update(I, Y) << "\n";
    }

}
#endif // mikevui
/*
5 8
1 8 9 10 12
7
2 9
4 8
1 12
0 12
3 4
1 9
0 1
*/

#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...