Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Campion - Runda 7 - Mess
- O (n * log(n) ^ 3)
- */
- #include <cstdio>
- #include <stdlib.h>
- #include <string.h>
- #include <ctime>
- #include <algorithm>
- using namespace std;
- #define Nmax 100010
- #define MAX (((long long)1 << 31) - 1)
- struct Treap {
- int key, priority, nrfii;
- Treap *left, *right;
- Treap (int key, int priority, int nrfii, Treap *left, Treap *right) {
- this->key = key;
- this->priority = priority;
- this->left = left;
- this->right = right;
- this->nrfii = nrfii;
- }
- };
- int n, m, p, q, k, rez, val, IS;
- int v[Nmax], on[Nmax], s[Nmax];
- Treap *AI[4 * Nmax], *nil;
- void read_data () {
- scanf ("%d %d", &n, &m);
- for (int i = 1; i <= n; i++) {
- scanf ("%d", &v[i]);
- s[i] = v[i];
- on[i] = 1;
- }
- sort (s + 1, s + n + 1);
- }
- void rotleft (Treap* &nod) {
- Treap *aux = nod->left;
- nod->left = aux->right; aux->right = nod;
- nod = aux;
- nod->nrfii = nod->left->nrfii + nod->right->nrfii + 1;
- }
- void rotright (Treap* &nod) {
- Treap *aux = nod->right;
- nod->right = aux->left; aux->left = nod;
- nod = aux;
- nod->nrfii = nod->left->nrfii + nod->right->nrfii + 1;
- }
- void balance (Treap* &nod) {
- if (nod->priority < nod->left->priority)
- rotleft (nod);
- if (nod->priority < nod->right->priority)
- rotright (nod);
- nod->nrfii = nod->left->nrfii + nod->left->nrfii;
- }
- void insert_treap (Treap* &nod, int key, int priority) {
- if (nod == nil) {
- nod = new Treap (key, priority, 1, nil, nil);
- return ;
- }
- if (key < nod->key) insert_treap (nod->left, key, priority);
- else if (key > nod->key) insert_treap (nod->right, key, priority);
- nod->nrfii = nod->left->nrfii + nod->right->nrfii + 1;
- balance (nod);
- nod->nrfii = nod->left->nrfii + nod->right->nrfii + 1;
- }
- void erase_treap (Treap* &nod, int key) {
- if (key < nod->key)
- erase_treap (nod->left, key);
- else {
- if (key > nod->key)
- erase_treap (nod->right, key);
- else {
- if (nod->left == nil && nod->right == nil)
- delete nod, nod = nil;
- else {
- if (nod->left->priority > nod->right->priority) rotleft (nod);
- else rotright (nod);
- erase_treap (nod, key);
- }
- }
- }
- if (nod != nil)nod->nrfii = nod->left->nrfii + nod->right->nrfii + 1;
- }
- #define MIJ ((st + dr) >> 1)
- #define N1 (nod << 1)
- #define N2 ((nod << 1) + 1)
- void make_arb (int nod, int st, int dr) {
- for (int i = st; i <= dr; i++) {
- insert_treap (AI[nod], v[i], rand () + 1);
- }
- if (st == dr)
- return ;
- make_arb (N1, st, MIJ);
- make_arb (N2, MIJ + 1, dr);
- }
- void update_arb (int nod, int st, int dr) {
- if (st <= p && p <= dr) {
- if (on[p] == 1) erase_treap (AI[nod], v[p]);
- else insert_treap (AI[nod], v[p], rand () + 1);
- return ;
- }
- if (p <= MIJ) update_arb (N1, st, MIJ);
- else update_arb (N2, MIJ + 1, dr);
- }
- int query_treap (Treap *nod, int val) {
- if (nod == nil) return 0;
- if (nod->key == val) return nod->left->nrfii;
- if (val < nod->key) return query_treap (nod->left, val);
- return query_treap (nod->right, val);
- }
- int find_treap (Treap *nod, int val) {
- if (nod == nil) return 0;
- if (nod->key == val) return 1;
- if (val < nod->key) return find_treap (nod->left, val);
- return find_treap (nod->right, val);
- }
- void query_arb (int nod, int st, int dr) {
- if (p <= st && dr <= q) {
- int ok = find_treap (AI[nod], val);
- if (ok) IS = 1;
- if (!ok) insert_treap (AI[nod], val, MAX);
- if (ok) {
- erase_treap (AI[nod], val);
- insert_treap (AI[nod], val, MAX);
- }
- rez+= query_treap (AI[nod], val);
- if (!ok) erase_treap (AI[nod], val);
- if (ok) {
- erase_treap (AI[nod], val);
- insert_treap (AI[nod], val, rand () + 1);
- }
- return ;
- }
- if (p <= MIJ) query_arb (N1, st, MIJ);
- if (MIJ < q) query_arb (N2, MIJ + 1, dr);
- }
- void solve () {
- int tip, st, dr, mij, sol = 0;
- // initializare treap
- nil = new Treap (0, 0, 0, NULL, NULL);
- int N = 4 * n;
- for (int i = 1; i <= N; i++)
- AI[i] = nil;
- make_arb (1, 1, n);
- for (; m; m--) {
- scanf ("%d", &tip);
- if (tip == 1) {
- // update
- scanf ("%d", &p);
- update_arb (1, 1, n);
- if (on[p] == 1) on[p] = 0;
- else on[p] = 1;
- }
- else {
- // query
- scanf ("%d %d %d", &p, &q, &k);
- st = 1; dr = n;
- while (st <= dr) {
- mij = (st + dr) >> 1;
- val = s[mij]; rez = 0; IS = 0; query_arb (1, 1, n);
- if (rez + 1 == k && IS) {
- sol = v[mij];
- break ;
- }
- if (rez + 1 <= k) st = mij + 1;
- else dr = mij - 1;
- }
- printf ("%d\n", sol);
- }
- }
- }
- int main () {
- freopen ("mess.in", "r", stdin);
- freopen ("mess.out", "w", stdout);
- //srand ( time (0) );
- read_data ();
- solve ();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement