[codevs1743] Reverse Card
Question Description
"DZY493941464|YYWYZDZR Original"
Small a neatly rows n cards, each of which has an integer of 1~n on each card, and each card has a different number.
For example, a case of N=5:3 4 2 1 5
Next you need to reverse the card according to the requirements of small A, so that the number on the first card on the left is 1. Operation Method: Make the number on the first card of the left number is K, if k=1 Stop the operation, otherwise the left number of 1~K card reversed.
After the first (K=3) reversal is obtained: 2 4 3 1 5
After the second (K=2) reversal is obtained: 4 2 3 1 5
After the third (K=4) reversal is obtained: 1 3 2 4 5
Visible Reversal 3 times, the number on the first card on the left becomes 1, the operation stops.
Your task is to calculate the number of times to reverse for an arrangement. You can assume that little a won't let you operate more than 100,000 times.
Input
Line 1th An integer N;
The 2nd row n integers, a full array of 1~n .
Output
Only 1 rows, outputting an integer representing the number of times to be manipulated.
If the requirement is still not met after a limited number of operations, output-1.
Input example
5 3 4 2 1 5
Output example
3
Data size and conventions
0<N≤ 300,000.
Exercises
Or a violent splay simulation ...
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <stack > #include <vector> #include <queue> #include <cstring> #include <string> #include <map > #include <set>using namespace std;const int buffersize = 1 << 16;char buffer[buffersize], *head, *TAIL;INL ine Char Getchar () {if (Head = = Tail) {int L = fread (buffer, 1, buffersize, stdin); Tail = (Head = buffer) + L; } return *head++;} int read () {int x = 0, f = 1; char c = Getchar (); while (!isdigit (c)) {if (c = = '-') f =-1; c = Getchar ();} while (IsDigit (c)) {x = x * + C-' 0 '; c = Getchar ();} return x * f;} #define MAXN 300010#define maxq 100000struct Node {int siz; bool Rev; Node (): Rev (0) {}} ns[maxn];int ToT, FA[MAXN], ch[maxn][2], a[maxn];void maintain (int o) {ns[o].siz = 1;for (int i = 0; I & Lt 2; i++) if (Ch[o][i]) Ns[o].siz + = Ns[ch[o][i]].siz;return;} void Build (int& o, int l, int r) {if (L > R)return; int mid = L + R >> 1; o = A[mid];build (ch[o][0], L, mid-1); Build (Ch[o][1], mid + 1, R), if (ch[o][0]) fa[ch[o][0]] = o;if (ch[o][1]) fa[ch[o][1]] = O;return maintain (o);} void pushdown (int o) {for (int i = 0; i < 2; i++) if (Ch[o][i]) Ns[ch[o][i]].rev ^= ns[o].rev;if (ns[o].rev) swap (ch[o][0], CH[O][1]), Ns[o].rev = 0;return;} void rotate (int u) {int y = Fa[u], z = fa[y], l = 0, r = 1;if (z) ch[z][ch[z][1]==y] = u;if (ch[y][1] = = u) Swap (L, R); Fa[u] = Z; Fa[y] = u; Fa[ch[u][r]] = y;ch[y][l] = Ch[u][r]; Ch[u][r] = Y;maintain (y); Maintain (U); return;} int S[MAXN], top;void splay (int u) {int t = u; S[top = 1] = T;while (fa[t]) T = fa[t], s[++top] = T;while (top) pushdown (s[top--]), while (Fa[u]) {int y = Fa[u], z = fa[y];i F (z) {if (ch[y][0] = = u ^ ch[z][0] = = y) rotate (u); else rotate (y);} Rotate (u);} return;} int split (int u) {if (!u) return splay (1), 1;splay (u), int tmp = ch[u][1];fa[tmp] = ch[u][1] = 0;return Maintain (u), tmp;} int merge (int a, int b) {if (!a) return B;pushdown (a); while (CH[A][1]) A = ch[a][1], pushdown (a); splay (a); ch[a][1] = b; FA[B] = A;return Maintain (a), A;} int Find (int o, int k) {pushdown (o); if (!o) return 0;int ls = ch[o][0]? ns[ch[o][0]].siz:0;if (k = = ls + 1) return O;if (k > ls + 1) return find (Ch[o][1], k-ls-1); return find (Ch[o][0], k);} int main () {int n = read (), for (int i = 1; I <= n; i++) A[i] = Read (), if (a[1] = = 1) return puts ("0"), 0;int tmp = 0, I; Build (TMP, 1, N), for (i = 1; I <= maxq; i++) {splay (1); int LRT = Find (1, find (1, 1)), RRT = Split (LRT); Ns[lrt].rev ^= 1; LRT = Merge (LRT, RRT), if (Find (LRT, 1) = = 1) break; printf ("%d\n", I <= maxq? I:-1); return 0;}
[codevs1743] Reverse Card