Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define endl "\n"
- using namespace std;
- using ll = long long;
- using ld = long double;
- using pii = pair<int, int>;
- constexpr int N = 3e5 + 5;
- struct Treap {
- struct Node {
- int val;
- int sz;
- int pri;
- Node *l, *r;
- Node(int val = 0) :
- val(val), sz(1),
- pri(rand() ^ (rand() << 16)),
- l(nullptr), r(nullptr){};
- };
- using pN = Node*;
- using pNN = pair<pN, pN>;
- Node buff[N];
- int st = 0;
- pN root = nullptr;
- int getsz(pN v) {
- return v == nullptr ? 0: v -> sz;
- }
- int getval(pN v) {
- return v == nullptr ? 0 : v -> val;
- }
- pN newN(int v) {
- buff[st] = Node(v);
- return &buff[st++];
- }
- void recalc(pN v) {
- v -> sz = getsz(v -> l) + getsz(v -> r) + 1;
- }
- pN merge(pN l, pN r) {
- if (l == nullptr)
- return r;
- if (r == nullptr)
- return l;
- if (l -> pri < r -> pri) {
- l -> r = merge(l -> r, r);
- recalc(l);
- return l;
- }
- else {
- r -> l = merge(l, r -> l);
- recalc(r);
- return r;
- }
- }
- pNN split(pN v, int k) {
- if (k == 0)
- return {nullptr, v};
- if (getsz(v -> l) >= k) {
- auto p = split(v -> l, k);
- v -> l = p.second;
- recalc(v);
- return {p.first, v};
- }
- else {
- auto p = split(v -> r, k - getsz(v -> l) - 1);
- v -> r = p.first;
- recalc(v);
- return {v, p.second};
- }
- }
- void insert(int pos, int val) {
- auto p1 = split(root, pos - 1);
- auto v = newN(val);
- root = merge(p1.first, merge(v, p1.second));
- return;
- }
- void erase(int pos) {
- auto p1 = split(root, pos - 1);
- auto p2 = split(p1.second, 1);
- root = merge(p1.first, p2.second);
- return;
- }
- int get_ans(int pos) {
- auto p1 = split(root, pos - 1);
- auto p2 = split(p1.second, 1);
- int ans = getval(p2.first);
- root = merge(merge(p2.first, p1.first), p2.second);
- return ans;
- }
- } tr;
- struct SegTree {
- vector<int> tr;
- SegTree(int n) {
- tr.resize(n << 2);
- }
- void upd(int pos, int val, int i, int l, int r) {
- if (l + 1 == r) {
- tr[i] += val;
- return;
- }
- int mid = (l + r) >> 1;
- if (pos < mid)
- upd(pos, val, (i << 1) + 1, l, mid);
- else
- upd(pos, val, (i << 1) + 2, mid, r);
- tr[i] = (tr[(i << 1) + 1] + tr[(i << 1) + 2]);
- }
- int get(int l, int r, int i, int cl, int cr) {
- if (l >= r)
- return 0;
- if (l == cl && r == cr)
- return tr[i];
- int mid = (cl + cr) >> 1;
- return
- get(l, min(mid, r), (i << 1) + 1, cl, mid) +
- get(max(l, mid), r, (i << 1) + 2, mid, cr);
- }
- };
- int n, m, type;
- vector<int> temp[N];
- vector<int> vec, dop;
- void Solve() {
- cin >> n >> m >> type;
- if (type == 2) {
- for (int i = 1; i <= m; i++)
- tr.insert(i, i);
- for (int i = 0, pos; i < n; i++) {
- cin >> pos;
- int a = tr.get_ans(pos);
- //assert(a > 0);
- cout << a << " ";
- }
- }
- else {
- for (int i = 0, v; i < n; i++) {
- cin >> v;
- vec.push_back(v);
- }
- dop = vec;
- reverse(dop.begin(), dop.end());
- for (int i = 1; i <= m; i++) {
- dop.push_back(i);
- }
- for (int i = 0; i < dop.size(); i++) {
- temp[dop[i]].push_back(i);
- }
- SegTree t(dop.size());
- for (int i = vec.size(); i < dop.size(); i++)
- t.upd(i, 1, 0, 0, dop.size());
- for (int i: vec) {
- int a = t.get(0, temp[i].back() + 1, 0, 0, dop.size());
- assert(a > 0);
- cout << a << ' ';
- t.upd(temp[i].back(), -1, 0, 0, dop.size());
- temp[i].pop_back();
- t.upd(temp[i].back(), 1, 0, 0, dop.size());
- }
- }
- }
- int main(){
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.tie(nullptr);
- //auto start = chrono::high_resolution_clock::now();
- Solve();
- //auto end = chrono::high_resolution_clock::now();
- //cout << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement