Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #pragma comment(linker, "/STACK:251700000")
- #include <iostream>
- #include <vector>
- #include <set>
- #include <string>
- #include <algorithm>
- #include <queue>
- #include <cstdio>
- #include <fstream>
- #include <unordered_map>
- #include <map>
- #include <iterator>
- #include <iomanip>
- #include <stack>
- #include <math.h>
- #include <bitset>
- #include <assert.h>
- //( ° ͜ʖ͡°)╭∩╮
- using namespace std;
- typedef long long ll;
- typedef pair<int, int> pii;
- typedef unsigned long long ull;
- typedef unsigned int ui;
- typedef vector<int> vi;
- #define TASK "clover"
- #define mp make_pair
- #define X first
- #define Y second
- #define all(a) (a).begin(), (a).end()
- #define inb push_back
- #define y1 lubluAU
- const ll LINF = 9e18;
- const int INF = 2e9;
- #ifdef _DEBUG
- const int M = 2e2 + 5;
- #else
- const int M = (1 << 18);
- #endif
- struct dd
- {
- int x, y, cnt, min;
- dd * l, *r;
- dd() {}
- dd(int x)
- {
- this->x = x;
- y = rand() << 15 + rand();
- cnt = min = x;
- l = r = NULL;
- }
- };
- typedef dd * node;
- int getc(node t)
- {
- if (t) return t->cnt;
- return 0;
- }
- int getm(node t)
- {
- if (t) return t->min;
- return INF;
- }
- void upd(node t)
- {
- if (!t) return;
- t->cnt = 1 + getc(t->l) + getc(t->r);
- }
- void updm(node t)
- {
- if (!t) return;
- t->min = min({ t->x, getm(t->l), getm(t->r) });
- }
- void split(node t, int x, node &l, node &r)
- {
- if (!t)
- {
- l = r = NULL;
- return;
- }
- if (x <= getc(t->l))
- split(t->l, x, l, t->l), r = t;
- else
- split(t->r, x - getc(t->l) - 1, t->r, r), l = t;
- upd(t);
- updm(t);
- }
- void merge(node &t, node l, node r)
- {
- if (!l || !r) t = l ? l : r;
- else if (l->y > r->y)
- merge(l->r, l->r, r), t = l;
- else
- merge(r->l, l, r->l), t = r;
- upd(t);
- updm(t);
- }
- void ins(node &t, int x, int pos)
- {
- node a, b, c, d;
- split(t, pos, a, b);
- split(b, 1, c, d);
- c = new dd(x);
- merge(b, c, d);
- merge(t, a, b);
- }
- void insert(node &t, int x, int l, int r)
- {
- node a, b, c, d, e, f;
- split(t, l, a, b);
- split(b, r - l, c, d);
- split(d, 1, e, f);
- e = new dd(x);
- merge(a, a, e);
- merge(b, c, f);
- merge(t, a, b);
- }
- void got(node t, int &x)
- {
- if (!t) return;
- if (!getm(t->l)) got(t->l, x);
- else
- {
- x += getc(t->l) + 1;
- if (t->x) got(t->r, x);
- }
- }
- int Find(node &t, int pos)
- {
- node a, b;
- split(t, pos, a, b);
- int ans = 0;
- got(b, ans);
- merge(t, a, b);
- return pos + ans - 1;
- }
- vi ans;
- void print(node t)
- {
- if (!t) return;
- print(t->l);
- ans.inb(t->x);
- print(t->r);
- }
- int main()
- {
- #ifdef _DEBUG
- freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
- #else
- //freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
- //freopen(TASK".in", "r", stdin), freopen(TASK".out", "w", stdout);
- #endif
- /*ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);*/
- int n, m;
- scanf("%d%d", &n, &m);
- vi l(n);
- for (int i = 0; i < n; ++i)
- scanf("%d", &l[i]), l[i]--;
- node root = NULL;
- for (int i = 0; i <= max(2 * n, 2 * m); ++i) merge(root, root, new dd(0));
- for (int i = 0; i < n; ++i)
- {
- int x = Find(root, l[i]);
- if (x == l[i])
- ins(root, i + 1, l[i]);
- else
- insert(root, i + 1, l[i], x);
- }
- ans.clear();
- print(root);
- while (ans.back() == 0) ans.pop_back();
- cout << ans.size() << '\n';
- for (int i : ans) cout << i << ' ';
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement