結果

問題 No.2809 Sort Query
ユーザー Tatsu_mr
提出日時 2024-08-11 21:13:18
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 1,922 ms / 2,000 ms
コード長 5,884 bytes
コンパイル時間 3,943 ms
コンパイル使用メモリ 220,476 KB
最終ジャッジ日時 2025-02-23 22:35:43
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 71
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <bits/stdc++.h>
using namespace std;
template <class T>
struct Treap {
private:
unsigned int xorshift() {
static unsigned int x = 123456789, y = 362436069, z = 521288629, w = 88675123;
unsigned int t = (x ^ (x << 11));
x = y;
y = z;
z = w;
return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}
struct Node {
Node *left, *right;
T value, mx;
int priority, size;
Node (T value_, int priority_) :
left(nullptr), right(nullptr), value(value_), mx(value_), priority(priority_), size(1) {}
};
using N = Node *;
N root = nullptr;
T INF = numeric_limits<T>::max();
bool multi;
map<T, int> mp;
int cnt(N t) {
return t ? t->size : 0;
}
T get_max(N t) {
return t ? t->mx : -INF;
}
void update(N t) {
if (t) {
t->size = cnt(t->left) + cnt(t->right) + 1;
t->mx = max({t->value, get_max(t->left), get_max(t->right)});
}
}
void merge(N &t, N l, N r) {
if (!l || !r) {
t = l ? l : r;
} else if (l->priority > r->priority) {
merge(l->right, l->right, r);
t = l;
} else {
merge(r->left, l, r->left);
t = r;
}
update(t);
}
void split(N t, T x, N &l, N &r) {
if (!t) {
l = nullptr;
r = nullptr;
} else if (x < t->value) {
split(t->left, x, l, t->left);
r = t;
} else {
split(t->right, x, t->right, r);
l = t;
}
update(t);
}
void insert(N &t, N n) {
if (!t) {
t = n;
} else if (n->priority > t->priority) {
split(t, n->value, n->left, n->right);
t = n;
} else {
insert(n->value < t->value ? t->left : t->right, n);
}
update(t);
}
void erase(N &t, T x) {
if (t->value == x) {
merge(t, t->left, t->right);
} else {
erase(x < t->value ? t->left : t->right, x);
}
update(t);
}
bool count(N &t, T x) {
if (!t) {
return false;
} else if (t->value == x) {
return true;
} else {
return count(x < t->value ? t->left : t->right, x);
}
}
T kth(N t, int k) {
int sz = cnt(t->left);
if (sz == k) {
return t->value;
}
return (sz > k ? kth(t->left, k) : kth(t->right, k - sz - 1));
}
pair<T, int> search(N t, T x, int i, bool equal) {
if (equal && t->value == x) {
return {t->value, i};
} else if (x < t->value) {
if ((equal && x <= get_max(t->left)) || (!equal && x < get_max(t->left))) {
return search(t->left, x, i - cnt(t->left->right) - 1, equal);
} else {
return {t->value, i};
}
} else {
if (!(t->right)) {
return {INF, -1};
}
return search(t->right, x, i + cnt(t->right->left) + 1, equal);
}
}
void dump(N t) {
if (!t) {
return;
}
dump(t->left);
cout << t->value << " ";
dump(t->right);
}
public:
Treap(bool multi_ = false) : multi(multi_) {}
Treap(vector<T> v, bool multi_ = false) : multi(multi_) {
for (auto x : v) {
insert(x);
}
}
void insert(T x) {
if (!multi && mp[x] > 0) {
return;
}
mp[x]++;
insert(root, new Node(x, xorshift()));
}
void erase(T x) {
if (mp[x] > 0) {
mp[x]--;
erase(root, x);
}
}
bool count(T x) {
return count(root, x);
}
int size() {
return cnt(root);
}
T operator[](int i) {
assert(0 <= i && i < cnt(root));
return kth(root, i);
}
pair<T, int> lower(T x) {
if (!root) {
return {INF, -1};
}
return search(root, x, cnt(root->left), true);
}
pair<T, int> upper(T x) {
if (!root) {
return {INF, -1};
}
return search(root, x, cnt(root->left), false);
}
void dump() {
dump(root);
cout << endl;
}
};
using lint = long long;
int main() {
int n, q;
cin >> n >> q;
vector<lint> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
Treap<lint> tr(a, true);
vector<lint> b(n, -1);
vector<pair<int, lint>> wait;
bool init = false;
while (q--) {
int t;
cin >> t;
if (t == 1) {
int k;
lint x;
cin >> k >> x;
k--;
b[k] = x;
wait.emplace_back(k, x);
} else if (t == 2) {
vector<lint> erase, insert;
for (auto [k, x] : wait) {
if (b[k] != x) {
continue;
}
erase.emplace_back(init ? tr[k] : a[k]);
insert.emplace_back(x);
b[k] = -1;
}
for (auto x : erase) {
tr.erase(x);
}
for (auto x : insert) {
tr.insert(x);
}
wait.clear();
erase.clear();
init = true;
} else {
int k;
cin >> k;
k--;
if (b[k] != -1) {
cout << b[k] << endl;
} else {
cout << (init ? tr[k] : a[k]) << endl;
}
}
/*tr.dump();
for (auto x : b) cout << x << " ";
cout << endl << endl;*/
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0