Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <iostream>
- #include <cmath>
- #include <algorithm>
- #include <vector>
- #include <string>
- #include <map>
- #include <iterator>
- #include <list>
- #include <set>
- #include <queue>
- #include <numeric>
- #include <cstdlib>
- #include <ctime>
- #include <climits>
- #include <cassert>
- using namespace std;
- typedef long long lli;
- typedef long li;
- template <class T>
- T Maximize (T &v, T nv) { if (nv > v) v = nv; return v; }
- template <class T>
- T Minimize (T &v, T nv) { if (nv < v) v = nv; return v; }
- const lli INFLL = LONG_LONG_MAX;
- const li INF = LONG_MAX;
- class Treap
- {
- static const li N = (li)3e5 + 1;
- struct Node
- {
- li pr, size, v;
- Node *l, *r;
- Node (li pr, li v) : pr(pr), v(v), l(0), r(0), size(1) {}
- void Update ()
- {
- size = SizeOf(l) + SizeOf(r) + 1;
- }
- void Print ()
- {
- printf("%ld", v);
- }
- li Index ()
- {
- return SizeOf(l) + 1;
- }
- inline static li SizeOf (Node *v)
- {
- return v ? v->size : 0;
- }
- static void Update (Node *v)
- {
- if (!v) return;
- v->Update();
- }
- static void Print (Node *v)
- {
- if (!v) return;
- Print(v->l);
- v->Print(), printf(" ");
- Print(v->r);
- }
- };
- private:
- Node *root;
- li prs[N], nodes;
- void merge (Node *l, Node *r, Node *&v)
- {
- if (!l || !r) return void(v = l ? l : r);
- if (l->pr > r->pr)
- {
- v = l;
- merge(l->r, r, v->r);
- }
- else
- {
- v = r;
- merge(l, r->l, v->l);
- }
- Node::Update(v);
- }
- void split (Node *v, li x, Node *&l, Node *&r)
- {
- if (!v) return void(l = r = 0);
- li key = v->Index();
- if (key <= x)
- {
- l = v;
- split(v->r, x - key, l->r, r);
- Node::Update(l);
- }
- else
- {
- r = v;
- split(v->l, x, l, r->l);
- Node::Update(r);
- }
- }
- void insert (Node *&r, Node *v, li x)
- {
- if (!r) return void(r = v);
- li pos = r->Index();
- if (v->pr > r->pr) split(r, x - 1, v->l, v->r), r = v;
- else if (x <= pos) insert(r->l, v, x);
- else insert(r->r, v, pos - x + 2);
- Node::Update(r);
- }
- void insert (Node *v, li x)
- {
- Node *l = 0, *r = 0;
- split(root, x - 1, l, r);
- merge(l, v, l);
- merge(l, r, root);
- }
- void erase (Node *&v, li x)
- {
- li pos = v->Index();
- if (pos == x) merge(v->l, v->r, v);
- else if (x < pos) erase(v->l, x);
- else erase(v->r, x - pos);
- Node::Update(v);
- }
- void generatePriorities ()
- {
- for (li i = 0; i < N; ++ i)
- {
- prs[i] = i;
- }
- random_shuffle(prs, prs + N);
- }
- public:
- Treap () : root(0), nodes(0)
- {
- generatePriorities();
- }
- void Insert (li v, li x)
- {
- //insert(root, NewNode(v), x);
- insert(NewNode(v), x);
- }
- void Erase (li x)
- {
- erase(root, x);
- /*Node *l = 0, *m = 0, *r = 0;
- split(root, x - 1, l, r);
- split(r, 1, m, r);
- assert(m);
- merge(l, r, root);*/
- }
- void Print ()
- {
- Node::Print(root);
- }
- void Print (li from, li to)
- {
- Node *l = 0, *m = 0, *r = 0;
- split(root, from - 1, l, r);
- split(r, to - from, m, r);
- Node::Print(m);
- merge(l, m, l);
- merge(l, r, root);
- }
- Node* NewNode (li v)
- {
- return new Node(prs[nodes++], v);
- }
- };
- void solve ()
- {
- li n, m;
- scanf("%ld %ld", &n, &m);
- srand(time(0));
- Treap *t = new Treap();
- set <li> zeros;
- for (li i = 1; i <= m; ++ i)
- {
- t->Insert(0, i);
- zeros.insert(i);
- }
- li maxpos = 0;
- for (li i = 1; i <= n; ++ i)
- {
- li pos;
- scanf("%ld", &pos);
- set<li>::iterator it = zeros.lower_bound(pos);
- if (it == zeros.end() || *it > maxpos)
- {
- maxpos ++;
- }
- if (it != zeros.end())
- {
- //printf("Delete zero at %ld\n", *it);
- t->Erase(*it);
- zeros.erase(it);
- }
- Maximize(maxpos, pos);
- //printf("%ld\n", maxpos);
- t->Insert(i, pos);
- //t->Print();
- //printf("\n");
- }
- printf("%ld\n", maxpos);
- t->Print(1, maxpos + 1);
- }
- void init ()
- {
- freopen("key.in", "r", stdin);
- freopen("key.out", "w", stdout);
- }
- int main()
- {
- init();
- solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement