Problem:
B: ピボット (Pivots)
問題
1
から
N
までの整数を並び変えた、長さ
N
の順列
a_1, a_2,  ..., a_N
が与えられる。
また、この順列に対して
Q
個のクエリが順に与えられる。
i
番目のクエリでは次の操作をしなければならない。
値
q_i
(
1 \leq q_i \leq N
) が与えられる。順列
\{a_1, a_2, ..., a_N\}
において
q_i
の左側の順列を
L
、
q_i
の右側の順列を
R
としたとき、元の順列
L \ \  q_i \ \  R
を
R \ \  q_i \ \  L
に変更する。つまり、
q_{i} = a_j
であるとき、順列
\{a_1, ..., a_{j-1}, a_j, a_{j+1}, ..., a_N\}
を
\{a_{j+1}, ..., a_N, a_j, a_1, ..., a_{j-1}\}
に変更する。
なお、順列
L
,
R
は空になることもあり得る。例えば
L
が空の時は、
q_i \ \  R
を
R \ \  q_i
に変更する。
R
が空のときについても同様である。
与えられた順列に対してこれら
Q
個のクエリを順に処理した後の順列を一行に出力せよ。
入力形式
N
Q
a_1 a_2 ... a_N
q_1 q_2 ... q_Q
入力は全て整数である。
一行目には順列の要素数
N
とクエリの回数
Q
が空白区切りで与えられる。
二行目には
1
から
N
までの整数を並び変えた順列
a_1, a_2, ..., a_N
が空白区切りで与えられる。
三行目にはクエリが
Q
個、空白区切りで与えられる。
q_i
は
i
番目のクエリを表す。
制約
1 \leq N \leq 10^5
1 \leq Q \leq 10^5
1 \leq a_i \leq N
a_i
は相異なる
1 \leq q_i \leq N
出力形式
クエリを順にすべて処理した後の順列を一行に出力せよ。
入力例1
5 2
1 5 3 2 4
5 2
出力例1
4 5 1 2 3
1番目のクエリにより、順列は
\{3, 2, 4, 5, 1\}
へ変わる。
2番目のクエリにより、順列は
\{4, 5, 1, 2, 3\}
へ変わる。
入力例2
5 1
1 2 3 4 5
5
出力例2
5 1 2 3 4

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

int N, A[1 << 19], NexA[1 << 19], Place[1 << 19], Next[1 << 19];
int Q, B[1 << 19];

void Query(int cl, int cr) {
    // Set Candidate
    vector<int> vec;
    vec.push_back(1);
    for (int i = cl; i < cr; i++) {
        int idx = B[i];
        vec.push_back(Place[idx]);
        if (Place[idx] != N) vec.push_back(Place[idx] + 1);
    }
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());

    // Calculate Next
    for (int i = 0; i < (int)vec.size(); i++) {
        if (i + 1 == (int)vec.size()) Next[vec[i]] = N + 1;
        else Next[vec[i]] = vec[i + 1];
    }

    // Get Value
    vector<int> val(cr - cl, 0);
    for (int i = cl; i < cr; i++) {
        for (int j = 0; j < (int)vec.size(); j++) {
            if (vec[j] == Place[B[i]]) val[i - cl] = j;
        }
    }

    // Simulate
    for (int i = cl; i < cr; i++) {
        vector<int> ret;
        vector<int> pl, pr;
        int state = 0;
        for (int j = 0; j < (int)vec.size(); j++) {
            if (vec[j] == Place[B[i]]) state = 1;
            else if (state == 0) pl.push_back(vec[j]);
            else if (state == 1) pr.push_back(vec[j]);
        }
        vec.clear();
        for (int j : pr) vec.push_back(j);
        vec.push_back(Place[B[i]]);
        for (int j : pl) vec.push_back(j);
        /*for (int j : vec) cout << j << " ";
        cout << endl;*/
    }

    // Fix
    int cur = 1;
    for (int i = 0; i < vec.size(); i++) {
        for (int j = vec[i]; j < Next[vec[i]]; j++) {
            NexA[cur] = A[j];
            cur += 1;
        }
    }
    for (int i = 1; i <= N; i++) A[i] = NexA[i];
    for (int i = 1; i <= N; i++) Place[A[i]] = i;
}

int main() {
    // Step 1. Input
    scanf("%d%d", &N, &Q);
    for (int i = 1; i <= N; i++) scanf("%d", &A[i]);
    for (int i = 1; i <= Q; i++) scanf("%d", &B[i]);
    for (int i = 1; i <= N; i++) Place[A[i]] = i;

    // Step 2. Sqrt Decomposition
    const int BACKET = 300;
    for (int i = 1; i <= Q; i += BACKET) {
        int cl = i;
        int cr = min(Q + 1, i + BACKET);
        Query(cl, cr);
    }

    // Step 3. Output
    for (int i = 1; i <= N; i++) {
        if (i >= 2) printf(" ");
        printf("%d", A[i]);
    }
    printf("\n");
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 12036
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=2167167167167167167;
const int INF=2100000000;
const ll mod=1e9+7;
#define rep(i,a) for (int i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}
template<class T> T min(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;}
template<class T> T max(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;}

void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	int N,Q;
	cin>>N>>Q;
	vector<int> p(N+1),rev(N+1);
	rep(i,N){
		cin>>p[i+1];
		rev[p[i+1]]=i+1;
	}
	rep(i,Q){
		int a=0,b;
		cin>>b;
		swap(rev[a],rev[b]);
		swap(p[rev[a]],p[rev[b]]);
	}
	int ind=rev[0]+1;
	rep(i,N){
		if(i) cout<<" ";
		cout<<p[(ind+i)%(N+1)];
	}
	cout<<"\n";
}
accuracy: 1
time_ms: 10
memory_kb: 3860
final_rank: 1

code_snippet: #line 1 "main.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2890"

#line 2 "lib/bbst/implicit_treap.hpp"

#line 2 "lib/prelude.hpp"
#ifndef LOCAL
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2")
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep2(i, m, n) for (auto i = (m); i < (n); i++)
#define rep(i, n) rep2(i, 0, n)
#define repr2(i, m, n) for (auto i = (n); i-- > (m);)
#define repr(i, n) repr2(i, 0, n)
#define all(x) begin(x), end(x)
template <class T>
auto ndvec(size_t n, T&& x) { return vector(n, forward<T>(x)); }
template <class... Ts>
auto ndvec(size_t n, Ts&&... xs) { return vector(n, forward<Ts>(xs)...); }
#line 3 "lib/bbst/iterator.hpp"

template <class Self, class Node, class T, bool Const>
class bidirectional_iterator_impl {
 public:
  using difference_type = ptrdiff_t;
  using value_type = T;
  using pointer = conditional_t<Const, const T *, T *>;
  using reference = conditional_t<Const, const T &, T &>;
  using iterator_category = bidirectional_iterator_tag;

 private:
  using self_type = Self;
  using node_pointer = conditional_t<Const, const Node *, Node *>;

 public:
  bidirectional_iterator_impl(Node *p) : ptr(p) { }
  bidirectional_iterator_impl(const Node *p = nullptr) : ptr(p) {} // ill-formed if !Const
  // reference operator*() const { return ptr->*Val(); }
  // pointer operator->() const { return &**this; }
  bool operator==(self_type rhs) const { return ptr == rhs.ptr; }
  bool operator!=(self_type rhs) const { return ptr != rhs.ptr; }
  self_type &operator++() {
    if (ptr->r) {
      ptr = ptr->r;
      while (ptr->l) ptr = ptr->l;
    } else {
      while (ptr->par->r == ptr) ptr = ptr->par;
      ptr = ptr->par;
    }
    return *(self_type *)this;
  }
  self_type operator++(int) {
    self_type res(ptr);
    ++*this;
    return res;
  }
  self_type &operator--() {
    if (ptr->l) {
      ptr = ptr->l;
      while (ptr->r) ptr = ptr->r;
    } else {
      while (ptr->par->l == ptr) ptr = ptr->par;
      ptr = ptr->par;
    }
    return *(self_type *)this;
  }
  self_type operator--(int) {
    self_type res(ptr);
    --*this;
    return res;
  }

  node_pointer ptr;
};
#line 3 "lib/bit/clz.hpp"

template <class T>
__attribute__ ((target ("lzcnt"))) int clz(T x) {
    if (!x) return sizeof(T) * 8;
    if constexpr (sizeof(T) <= sizeof(int)) {
        return __builtin_clz((int)x);
    } else if constexpr (sizeof(T) <= sizeof(ll)) {
        return __builtin_clzll((ll)x);
    } else if constexpr (sizeof(T) <= sizeof(ll) * 2) {
        int l = clz((ll)(x >> sizeof(ll) * 8));
        return l != sizeof(ll) * 8 ? l : l + clz((ll)x);
    }
}
#line 4 "lib/bit/ilog2.hpp"

template <class T>
int ilog2(T x) { assert(x != 0); return sizeof(T) * 8 - 1 - clz(x); }

template <class T>
int ilog2_ceil(T x) { return x == 0 || x == 1 ? 1 : ilog2(x - 1) + 1; }

template <class T>
T bit_floor(T x) { return T(1) << ilog2(x); }

template <class T>
T bit_ceil(T x) { return T(1) << ilog2_ceil(x); }
#line 3 "lib/func/no_op.hpp"

struct no_op {
  template <class... Ts>
  void operator()(Ts&&...) const {}
};
#line 3 "lib/util/pool.hpp"

template <size_t N = 1 << 20>
struct pool {
  template <class T>
  struct alloc {
    static inline T* ptr =
        (T*)new (align_val_t(alignof(T))) unsigned char[sizeof(T) * N];
    static void* operator new(size_t) noexcept { return ptr++; }
    static void operator delete(void* p) { destroy_at((T*)p); }

   private:
    alloc() = default;
    friend T;
  };
};

struct no_pool {
  template <class T>
  struct alloc {};
};
#line 3 "lib/util/seed.hpp"

auto seed() {
  return chrono::steady_clock::now().time_since_epoch().count();
}
#line 3 "lib/util/rand.hpp"

uint32_t rand32() {
  static uint32_t x = seed();
  x ^= x << 13;
  x ^= x >> 17;
  x ^= x << 5;
  return x;
}
#line 8 "lib/bbst/implicit_treap.hpp"

template <class T, class Update = no_op, class Propagate = no_op,
          class Alloc = pool<>>
class implicit_treap {
  class node;
  class node_base;
  using link = node_base *;
  using clink = const node_base *;

  class node_base {
   public:
    link l = nullptr, r = nullptr, par = nullptr;
    int cnt = 1;
    uint32_t key = rand32();
    T &val() { return ((node *)this)->val; }
    const T &val() const { return ((const node *)this)->val; }
  };
  class node : public node_base, public Alloc::template alloc<node> {
   public:
    T val;
    node(T val) : val(move(val)) {}
  };

 private:
 public:
  class iterator
      : public bidirectional_iterator_impl<iterator, node_base, T, false> {
    using base_type =
        bidirectional_iterator_impl<iterator, node_base, T, false>;

   public:
    using base_type::base_type;
    T &operator*() const { return base_type::ptr->val(); }
    T *operator->() const { return &**this; }
  };

  class const_iterator
      : public bidirectional_iterator_impl<const_iterator, node_base, T, true> {
    using base_type =
        bidirectional_iterator_impl<const_iterator, node_base, T, true>;

   public:
    using base_type::base_type;
    const_iterator(iterator it) : base_type(it.ptr) {}
    const T &operator*() const { return base_type::ptr->val(); }
    const T *operator->() const { return &**this; }
  };

 public:
  implicit_treap(Update upd = Update(), Propagate prop = Propagate())
      : upd(upd), prop(prop) {}
  template <class It>
  implicit_treap(It a, It a_last, Update upd = Update(),
                 Propagate prop = Propagate())
      : upd(upd), prop(prop) {
    vector<link> ps(bit_ceil(distance(a, a_last)) * 2);
    for (auto it = ps.begin(); a != a_last; it++, a++)
      *it = (link) new node(*a);
    for (int i = 0; i + 1 < ps.size(); i += 2)
      ps.push_back(merge(ps[i], ps[i + 1]));
    set_l(&head, ps.back());
  }

  implicit_treap(const implicit_treap &rhs) : upd(rhs.upd), prop(rhs.prop) {
    set_l(&head, deep_copy(rhs.head.l));
  }
  implicit_treap(implicit_treap &&rhs) : upd(rhs.upd), prop(rhs.prop) {
    set_l(&head, rhs.head.l);
    rhs.head.l = nullptr;
  }
  implicit_treap &operator=(const implicit_treap &rhs) {
    set_l(&head, deep_copy(rhs.head.l));
    return *this;
  }
  implicit_treap &operator=(implicit_treap &&rhs) {
    set_l(&head, rhs.head.l), rhs.head.l = nullptr;
    return *this;
  }

  const_iterator begin() const {
    auto ptr = &head;
    while (ptr->l) ptr = ptr->l;
    return const_iterator(ptr);
  }
  const_iterator end() const { return const_iterator(&head); }
  const_iterator croot() const {
    return const_iterator(head.l ? head.l : &head);
  }
  const_iterator root() const { return croot(); }
  iterator root() { return iterator(head.l ? head.l : &head); }
  const_iterator find(int k) const { return const_iterator(find(head.l, k)); }

  template <class F>
  void apply_on(int i, int j, F f) {
    if (i == j) return;
    auto [lm, r] = split(j);
    auto [l, m] = lm.split(i);
    f(m.root());
    *this = move(l.append(m).append(r));
  }

  int size() const { return count(head.l); }
  implicit_treap &append(implicit_treap &rhs) {
    set_l(&head, merge(head.l, rhs.head.l));
    rhs.head.l = nullptr;
    return *this;
  }
  pair<implicit_treap, implicit_treap> split(int k) {
    auto [l, r] = split(head.l, k);
    implicit_treap left(l, upd, prop);
    set_l(&head, r);
    return pair(move(left), move(*this));
  }
  pair<implicit_treap, implicit_treap> raw_split(int k) {
    auto [l, r] = raw_split(head.l, k);
    implicit_treap left(l, upd, prop);
    set_l(&head, r);
    return pair(move(left), move(*this));
  }
  const_iterator insert(int k, T v) {
    auto [l, r] = split(k);
    auto p = (link) new node(move(v));
    implicit_treap m(p, upd, prop);
    set_l(&head, l.append(m).append(r).head.l);
    return const_iterator(p);
  }
  void erase(const_iterator it) {
    if (it.ptr == it.ptr->par->l)
      set_l(it.ptr->par, merge(it.ptr->l, it.ptr->r)), update(*it.ptr->par);
    else
      set_r(it.ptr->par, merge(it.ptr->l, it.ptr->r)), update(*it.ptr->par);
  }
  int index_of(const_iterator it) {
    auto p = const_cast<link>(it.ptr);
    prop(*p);
    int ans = count(p->l);
    for (; p->par != &head; p = p->par) {
      if (p->par->r == p) ans += count(p->par->l) + 1;
      auto l0 = p->par->l;
      prop(*p->par);
      if (l0 != p->par->l) ans = count(p->par) - ans - 1;
    }
    return ans;
  }
  void propagate_all() {
    propagate_all(head.l);
  }

 private:
  implicit_treap(link root, Update upd, Propagate prop) : upd(upd), prop(prop) {
    set_l(&head, root);
  }

  node_base head;
  Update upd;
  Propagate prop;
  int count(link p) const { return p ? p->cnt : 0; }
  void update(node_base &n) { update((node &)n); }
  void update(node &n) {
    n.cnt = 1 + count(n.l) + count(n.r);
    upd((node_base &)n);
  }
  void set_l(link par, link p) {
    par->l = p;
    if (p) p->par = par;
  }
  void set_r(link par, link p) {
    par->r = p;
    if (p) p->par = par;
  }
  link merge(link l, link r) {
    if (!l) return r;
    if (!r) return l;
    if (l->key > r->key) {
      return prop(*l), set_r(l, merge(l->r, r)), update(*l), l;
    } else {
      return prop(*r), set_l(r, merge(l, r->l)), update(*r), r;
    }
  }
  pair<link, link> split(link p, int k) {
    if (!p) {
      assert(k == 0);
      return pair(nullptr, nullptr);
    }
    prop(*p);
    if (count(p->l) < k) {
      auto [l, r] = split(p->r, k - count(p->l) - 1);
      set_r(p, l), update(*p);
      return pair(p, r);
    } else {
      auto [l, r] = split(p->l, k);
      set_l(p, r), update(*p);
      return pair(l, p);
    }
  }
  pair<link, link> raw_split(link p, int k) {
    if (!p) {
      assert(k == 0);
      return pair(nullptr, nullptr);
    }
    prop(*p);
    if (count(p->l) < k) {
      auto [l, r] = split(p->r, k - count(p->l) - 1);
      set_r(p, l), update(*p);
      return pair(p, r);
    } else {
      auto [l, r] = split(p->l, k);
      set_l(p, r), update(*p);
      return pair(l, p);
    }
  }
  link find(link p, int k) {
    return count(p->l) == k  ? p
           : count(p->l) < k ? find(p->r, k - count(p->l) - 1)
                             : find(p->l, k);
  }
  link deep_copy(link p) {
    if (!p) return nullptr;
    link q = (link) new node(*(node *)p);
    set_l(q, deep_copy(p->l));
    set_r(q, deep_copy(p->r));
    return q;
  }
  void propagate_all(link p) {
    if (!p) return;
    prop(*p);
    propagate_all(p->l), propagate_all(p->r);
  }
};
#line 4 "main.cpp"

int main() {
  int n, q;
  scanf("%d%d", &n, &q);

  auto prop = [&](auto &n) {
    if (!n.val().second) return;
    swap(n.l, n.r);
    if (n.l) n.l->val().second ^= true;
    if (n.r) n.r->val().second ^= true;
    n.val().second = false;
  };
  implicit_treap<pair<int, bool>, no_op, decltype(prop)> tree(no_op{}, prop);
  vector<decltype(tree.begin())> its(n+1);

  rep(i, n) {
    int a; scanf("%d", &a);
    its[a] = tree.insert(i, {a, false});
  }
  bool flip = q % 2;
  while (q--) {
    int x; scanf("%d", &x);
    int k = tree.index_of(its[x]);
    tree.apply_on(0, k, [](auto p) { p->second ^= true; });
    tree.apply_on(k + 1, n, [](auto p) { p->second ^= true; });
  }
  if (flip) tree.root()->second ^= true;
  tree.propagate_all();
  decltype(tree)::const_iterator it = tree.begin();
  printf("%d", it++->first);
  while (it != tree.end()) printf(" %d", it++->first);
  printf("\n");
}
accuracy: 1
time_ms: 100
memory_kb: 9560
final_rank: 11

code_snippet: #line 1 "main.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2890"

#line 2 "lib/bbst/implicit_treap.hpp"

#line 2 "lib/prelude.hpp"
#ifndef LOCAL
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2")
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep2(i, m, n) for (auto i = (m); i < (n); i++)
#define rep(i, n) rep2(i, 0, n)
#define repr2(i, m, n) for (auto i = (n); i-- > (m);)
#define repr(i, n) repr2(i, 0, n)
#define all(x) begin(x), end(x)
template <class T>
auto ndvec(size_t n, T&& x) { return vector(n, forward<T>(x)); }
template <class... Ts>
auto ndvec(size_t n, Ts&&... xs) { return vector(n, forward<Ts>(xs)...); }
#line 3 "lib/bbst/iterator.hpp"

template <class Self, class Node, class T, bool Const>
class bidirectional_iterator_impl {
 public:
  using difference_type = ptrdiff_t;
  using value_type = T;
  using pointer = conditional_t<Const, const T *, T *>;
  using reference = conditional_t<Const, const T &, T &>;
  using iterator_category = bidirectional_iterator_tag;

 private:
  using self_type = Self;
  using node_pointer = conditional_t<Const, const Node *, Node *>;

 public:
  bidirectional_iterator_impl(Node *p) : ptr(p) { }
  bidirectional_iterator_impl(const Node *p = nullptr) : ptr(p) {} // ill-formed if !Const
  // reference operator*() const { return ptr->*Val(); }
  // pointer operator->() const { return &**this; }
  bool operator==(self_type rhs) const { return ptr == rhs.ptr; }
  bool operator!=(self_type rhs) const { return ptr != rhs.ptr; }
  self_type &operator++() {
    if (ptr->r) {
      ptr = ptr->r;
      while (ptr->l) ptr = ptr->l;
    } else {
      while (ptr->par->r == ptr) ptr = ptr->par;
      ptr = ptr->par;
    }
    return *(self_type *)this;
  }
  self_type operator++(int) {
    self_type res(ptr);
    ++*this;
    return res;
  }
  self_type &operator--() {
    if (ptr->l) {
      ptr = ptr->l;
      while (ptr->r) ptr = ptr->r;
    } else {
      while (ptr->par->l == ptr) ptr = ptr->par;
      ptr = ptr->par;
    }
    return *(self_type *)this;
  }
  self_type operator--(int) {
    self_type res(ptr);
    --*this;
    return res;
  }

  node_pointer ptr;
};
#line 3 "lib/bit/clz.hpp"

template <class T>
__attribute__ ((target ("lzcnt"))) int clz(T x) {
    if (!x) return sizeof(T) * 8;
    if constexpr (sizeof(T) <= sizeof(int)) {
        return __builtin_clz((int)x);
    } else if constexpr (sizeof(T) <= sizeof(ll)) {
        return __builtin_clzll((ll)x);
    } else if constexpr (sizeof(T) <= sizeof(ll) * 2) {
        int l = clz((ll)(x >> sizeof(ll) * 8));
        return l != sizeof(ll) * 8 ? l : l + clz((ll)x);
    }
}
#line 4 "lib/bit/ilog2.hpp"

template <class T>
int ilog2(T x) { assert(x != 0); return sizeof(T) * 8 - 1 - clz(x); }

template <class T>
int ilog2_ceil(T x) { return x == 0 || x == 1 ? 1 : ilog2(x - 1) + 1; }

template <class T>
T bit_floor(T x) { return T(1) << ilog2(x); }

template <class T>
T bit_ceil(T x) { return T(1) << ilog2_ceil(x); }
#line 3 "lib/func/no_op.hpp"

struct no_op {
  template <class... Ts>
  void operator()(Ts&&...) const {}
};
#line 3 "lib/util/pool.hpp"

template <size_t N = 1 << 20>
struct pool {
  template <class T>
  struct alloc {
    static inline T* ptr =
        (T*)new (align_val_t(alignof(T))) unsigned char[sizeof(T) * N];
    static void* operator new(size_t) noexcept { return ptr++; }
    static void operator delete(void* p) { destroy_at((T*)p); }

   private:
    alloc() = default;
    friend T;
  };
};

struct no_pool {
  template <class T>
  struct alloc {};
};
#line 3 "lib/util/seed.hpp"

auto seed() {
  return chrono::steady_clock::now().time_since_epoch().count();
}
#line 3 "lib/util/rand.hpp"

uint32_t rand32() {
  static uint32_t x = seed();
  x ^= x << 13;
  x ^= x >> 17;
  x ^= x << 5;
  return x;
}
#line 8 "lib/bbst/implicit_treap.hpp"

template <class T, class Update = no_op, class Propagate = no_op,
          class Alloc = pool<>>
class implicit_treap {
  class node;
  class node_base;
  using link = node_base *;
  using clink = const node_base *;

  class node_base {
   public:
    link l = nullptr, r = nullptr, par = nullptr;
    int cnt = 1;
    uint32_t key = rand32();
    T &val() { return ((node *)this)->val; }
    const T &val() const { return ((const node *)this)->val; }
  };
  class node : public node_base, public Alloc::template alloc<node> {
   public:
    T val;
    node(T val) : val(move(val)) {}
  };

 private:
 public:
  class iterator
      : public bidirectional_iterator_impl<iterator, node_base, T, false> {
    using base_type =
        bidirectional_iterator_impl<iterator, node_base, T, false>;

   public:
    using base_type::base_type;
    T &operator*() const { return base_type::ptr->val(); }
    T *operator->() const { return &**this; }
  };

  class const_iterator
      : public bidirectional_iterator_impl<const_iterator, node_base, T, true> {
    using base_type =
        bidirectional_iterator_impl<const_iterator, node_base, T, true>;

   public:
    using base_type::base_type;
    const_iterator(iterator it) : base_type(it.ptr) {}
    const T &operator*() const { return base_type::ptr->val(); }
    const T *operator->() const { return &**this; }
  };

 public:
  implicit_treap(Update upd = Update(), Propagate prop = Propagate())
      : upd(upd), prop(prop) {}
  template <class It>
  implicit_treap(It a, It a_last, Update upd = Update(),
                 Propagate prop = Propagate())
      : upd(upd), prop(prop) {
    vector<link> ps(bit_ceil(distance(a, a_last)) * 2);
    for (auto it = ps.begin(); a != a_last; it++, a++)
      *it = (link) new node(*a);
    for (int i = 0; i + 1 < ps.size(); i += 2)
      ps.push_back(merge(ps[i], ps[i + 1]));
    set_l(&head, ps.back());
  }

  implicit_treap(const implicit_treap &rhs) : upd(rhs.upd), prop(rhs.prop) {
    set_l(&head, deep_copy(rhs.head.l));
  }
  implicit_treap(implicit_treap &&rhs) : upd(rhs.upd), prop(rhs.prop) {
    set_l(&head, rhs.head.l);
    rhs.head.l = nullptr;
  }
  implicit_treap &operator=(const implicit_treap &rhs) {
    set_l(&head, deep_copy(rhs.head.l));
    return *this;
  }
  implicit_treap &operator=(implicit_treap &&rhs) {
    set_l(&head, rhs.head.l), rhs.head.l = nullptr;
    return *this;
  }

  const_iterator begin() const {
    auto ptr = &head;
    while (ptr->l) ptr = ptr->l;
    return const_iterator(ptr);
  }
  const_iterator end() const { return const_iterator(&head); }
  const_iterator croot() const {
    return const_iterator(head.l ? head.l : &head);
  }
  const_iterator root() const { return croot(); }
  iterator root() { return iterator(head.l ? head.l : &head); }
  const_iterator find(int k) const { return const_iterator(find(head.l, k)); }

  template <class F>
  void apply_on(int i, int j, F f) {
    if (i == j) return;
    auto [lm, r] = split(j);
    auto [l, m] = lm.split(i);
    f(m.root());
    *this = move(l.append(m).append(r));
  }

  int size() const { return count(head.l); }
  implicit_treap &append(implicit_treap &rhs) {
    set_l(&head, merge(head.l, rhs.head.l));
    rhs.head.l = nullptr;
    return *this;
  }
  pair<implicit_treap, implicit_treap> split(int k) {
    auto [l, r] = split(head.l, k);
    implicit_treap left(l, upd, prop);
    set_l(&head, r);
    return pair(move(left), move(*this));
  }
  pair<implicit_treap, implicit_treap> raw_split(int k) {
    auto [l, r] = raw_split(head.l, k);
    implicit_treap left(l, upd, prop);
    set_l(&head, r);
    return pair(move(left), move(*this));
  }
  const_iterator insert(int k, T v) {
    auto [l, r] = split(k);
    auto p = (link) new node(move(v));
    implicit_treap m(p, upd, prop);
    set_l(&head, l.append(m).append(r).head.l);
    return const_iterator(p);
  }
  void erase(const_iterator it) {
    if (it.ptr == it.ptr->par->l)
      set_l(it.ptr->par, merge(it.ptr->l, it.ptr->r)), update(*it.ptr->par);
    else
      set_r(it.ptr->par, merge(it.ptr->l, it.ptr->r)), update(*it.ptr->par);
  }
  int index_of(const_iterator it) {
    int ans = count(it.ptr->l);
    for (auto p = it.ptr; p->par != &head; p = p->par) {
      if (p->par->r == p) ans += count(p->par->l) + 1;
      auto l0 = p->par->l;
      prop(*p->par);
      if (l0 != p->par->l) ans = count(p->par) - ans - 1;
    }
    return ans;
  }
  void propagate_all() {
    propagate_all(head.l);
  }

 private:
  implicit_treap(link root, Update upd, Propagate prop) : upd(upd), prop(prop) {
    set_l(&head, root);
  }

  node_base head;
  Update upd;
  Propagate prop;
  int count(link p) const { return p ? p->cnt : 0; }
  void update(node_base &n) { update((node &)n); }
  void update(node &n) {
    n.cnt = 1 + count(n.l) + count(n.r);
    upd((node_base &)n);
  }
  void set_l(link par, link p) {
    par->l = p;
    if (p) p->par = par;
  }
  void set_r(link par, link p) {
    par->r = p;
    if (p) p->par = par;
  }
  link merge(link l, link r) {
    if (!l) return r;
    if (!r) return l;
    if (l->key > r->key) {
      return prop(*l), set_r(l, merge(l->r, r)), update(*l), l;
    } else {
      return prop(*r), set_l(r, merge(l, r->l)), update(*r), r;
    }
  }
  pair<link, link> split(link p, int k) {
    if (!p) {
      assert(k == 0);
      return pair(nullptr, nullptr);
    }
    prop(*p);
    if (count(p->l) < k) {
      auto [l, r] = split(p->r, k - count(p->l) - 1);
      set_r(p, l), update(*p);
      return pair(p, r);
    } else {
      auto [l, r] = split(p->l, k);
      set_l(p, r), update(*p);
      return pair(l, p);
    }
  }
  pair<link, link> raw_split(link p, int k) {
    if (!p) {
      assert(k == 0);
      return pair(nullptr, nullptr);
    }
    prop(*p);
    if (count(p->l) < k) {
      auto [l, r] = split(p->r, k - count(p->l) - 1);
      set_r(p, l), update(*p);
      return pair(p, r);
    } else {
      auto [l, r] = split(p->l, k);
      set_l(p, r), update(*p);
      return pair(l, p);
    }
  }
  link find(link p, int k) {
    return count(p->l) == k  ? p
           : count(p->l) < k ? find(p->r, k - count(p->l) - 1)
                             : find(p->l, k);
  }
  link deep_copy(link p) {
    if (!p) return nullptr;
    link q = (link) new node(*(node *)p);
    set_l(q, deep_copy(p->l));
    set_r(q, deep_copy(p->r));
    return q;
  }
  void propagate_all(link p) {
    if (!p) return;
    prop(*p);
    propagate_all(p->l), propagate_all(p->r);
  }
};
#line 4 "main.cpp"

int main() {
  int n, q;
  scanf("%d%d", &n, &q);

  auto prop = [&](auto &n) {
    if (!n.val().second) return;
    swap(n.l, n.r);
    if (n.l) n.l->val().second ^= true;
    if (n.r) n.r->val().second ^= true;
    n.val().second = false;
  };
  implicit_treap<pair<int, bool>, no_op, decltype(prop)> tree(no_op{}, prop);
  vector<decltype(tree.begin())> its(n+1);

  rep(i, n) {
    int a; scanf("%d", &a);
    its[a] = tree.insert(i, {a, false});
  }
  bool flip = q % 2;
  while (q--) {
    int x; scanf("%d", &x);
    int k = tree.index_of(its[x]);
    tree.apply_on(0, k, [](auto p) { p->second ^= true; });
    tree.apply_on(k + 1, n, [](auto p) { p->second ^= true; });
  }
  if (flip) tree.root()->second ^= true;
  tree.propagate_all();
  decltype(tree)::const_iterator it = tree.begin();
  printf("%d", it++->first);
  while (it != tree.end()) printf(" %d", it++->first);
  printf("\n");
}
accuracy: 0.05714285714285714
time_ms: 100
memory_kb: 9000
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
#include <algorithm>
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define ALL(a)  (a).begin(),(a).end()
using ll = long long;
using P = pair<int,int>;
using T = tuple<int,int,int>;
using Graph = vector<vector<int>>;
const int INF = 1001001001;
// const ll INF = 1100100100100100100;
const ll MOD = 1000000007;
void printVec(vector<int> &vec) {
  for (auto itr = vec.begin(); itr != vec.end(); itr++) cout << *itr << " "; 
  cout << endl;
}
vector<int> next_h = {1, -1, 0, 0};
vector<int> next_w = {0, 0, 1, -1};
struct Node {
  Node *prev, *next;
  int key;
  Node(int key) : prev(NULL), next(NULL), key(key) {}
};

int main() {
  int N, Q; cin >> N >> Q;
  Node* nil;
  nil = new Node(-1);
  vector<Node*> vec(N);
  rep(i,N) {
    Node* node = new Node(i);
    node->prev = nil;
    node->next = nil;
    vec[i] = node;
  }
  vector<int> a(N);
  rep(i,N) cin >> a[i], a[i]--;
  rep(i,N) {
    if(i > 0) vec[a[i]]->prev = vec[a[i-1]];
    if(i < N-1) vec[a[i]]->next = vec[a[i+1]];
  }
  Node* head = new Node(-2);
  Node* tail = new Node(-2);
  head->next = vec[a[0]];
  tail->next = vec[a[N-1]];
  rep(i,Q) {
    int q; cin >> q; q--;
    if(vec[q]->prev == nil) {  // 先頭だったとき
      Node* next_node = vec[q]->next;
      next_node->prev = nil;
      Node* tail_node = tail->next;
      tail_node->next = vec[q];
      vec[q]->prev = tail_node;
      vec[q]->next = nil;
      head->next = next_node;
      tail->next = vec[q];
    } else if(vec[q]->next == nil) {  // 末尾だったとき
      Node* prev_node = vec[q]->prev;
      prev_node->next = nil;
      Node* head_node = head->next;
      head_node->prev = vec[q];
      vec[q]->prev = nil;
      vec[q]->next = head_node;
      head->next = vec[q];
      tail->next = prev_node;
    } else {  // それ以外
      Node* prev_node = vec[q]->prev;
      Node* next_node = vec[q]->next;
      prev_node->next = nil;
      next_node->prev = nil;
      Node* head_node = head->next;
      Node* tail_node = tail->next;
      head_node->prev = vec[q];
      tail_node->next = vec[q];
      vec[q]->prev = tail_node;
      vec[q]->next = head_node;
      head->next = next_node;
      tail->next = prev_node;
    }
  }
  head = head->next;
  while(head != nil) {
    cout << head->key + 1;
    head = head->next;
    if(head != nil) cout << " ";
  }
  cout << endl;
  return 0;
}
accuracy: 0.9142857142857143
time_ms: 30
memory_kb: 7268
final_rank: 19

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2890

#include<bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename Impl, typename Data, typename Node, size_t LIM>
struct RBST{
  using u32 = uint32_t;
  u32 xor128(){
    static u32 x = 123456789;
    static u32 y = 362436069;
    static u32 z = 521288629;
    static u32 w = 88675123;

    u32 t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  }

  alignas(Node) static inline char pool[sizeof(Node)*LIM];
  static inline Node* ptr = (Node*)pool;
  static inline size_t size;

  template<typename... Args>
  inline Node* create(Args&&... args){
    return new (ptr+size++) Node(std::forward<Args>(args)...);
  }

  inline size_t count(const Node *t){return Data::count(t);}

  inline Node* touch(Node *t){
    return static_cast<Impl*>(this)->touch(t);
  }

  inline void toggle(Node *t){
    return static_cast<Impl*>(this)->toggle(t);
  }

  inline Node* pushup(Node *t){
    return static_cast<Impl*>(this)->pushup(t);
  }

  Node* toggle(Node *a,size_t l,size_t r){
    auto s=split(a,l);
    auto t=split(s.second,r-l);
    auto u=touch(t.first);
    toggle(u);
    return merge(s.first,merge(u,t.second));
  }

  Node* merge(Node* a,Node* b){
    if(a==nullptr) return b;
    if(b==nullptr) return a;
    if(xor128()%(count(a)+count(b))<count(a)){
      a=touch(a);
      a->r=merge(a->r,b);
      a->r->p=a;
      return pushup(a);
    }
    b=touch(b);
    b->l=merge(a,b->l);
    b->l->p=b;
    return pushup(b);
  }

  pair<Node*, Node*> split(Node* a,size_t k){
    if(a==nullptr) return make_pair(a,a);
    a=touch(a);
    if(k<=count(a->l)){
      if(a->l) a->l->p=nullptr;
      auto s=split(a->l,k);
      a->l=s.second;
      if(a->l) a->l->p=a;
      return make_pair(s.first,pushup(a));
    }
    if(a->r) a->r->p=nullptr;
    auto s=split(a->r,k-(count(a->l)+1));
    a->r=s.first;
    if(a->r) a->r->p=a;
    return make_pair(pushup(a),s.second);
  }

  Node* insert(Node *a,size_t k,Node v){
    Node* b=create(v);
    auto s=split(a,k);
    return merge(merge(s.first,b),s.second);
  }

  Node* erase(Node *a,size_t k){
    assert(k<count(a));
    auto s=split(a,k);
    auto t=split(s.second,1);
    return merge(s.first,t.second);
  }

  Node* find_by_order(Node *a,size_t k){
    assert(k<count(a));
    a=touch(a);
    size_t num=count(a->l);
    if(k<num) return find_by_order(a->l,k);
    if(k>num) return find_by_order(a->r,k-(num+1));
    return a;
  }

  inline bool is_right(Node* a){
    return a->p and a->p->r==a;
  }

  size_t order_of_key(Node* a){
    size_t res=count(a->l);
    while(a){
      if(is_right(a)) res+=count(a->p->l)+1;
      a=a->p;
    }
    return res;
  }

  Node* build(size_t l,size_t r,const vector<Node> &vs){
    if(l+1==r) return create(vs[l]);
    size_t m=(l+r)>>1;
    return merge(build(l,m,vs),build(m,r,vs));
  }

  Node* build(const vector<Node> &vs){
    return build(0,vs.size(),vs);
  }

  template<typename T>
  Node* set_val(Node *a,size_t k,T val){
    assert(k<count(a));
    a=touch(a);
    size_t num=count(a->l);
    if(k<num) a->l=set_val(a->l,k,val);
    if(k>num) a->r=set_val(a->r,k-(num+1),val);
    if(k==num) a->val=val;
    return pushup(a);
  }

  Node* get_val(Node *a,size_t k){
    assert(k<count(a));
    a=touch(a);
    size_t num=count(a->l);
    if(k<num) return get_val(a->l,k);
    if(k>num) return get_val(a->r,k-(num+1));
    return a;
  }

  template<typename E>
  Node* update(Node *a,size_t l,size_t r,E v){
    auto s=split(a,l);
    auto t=split(s.second,r-l);
    auto u=touch(t.first);
    propagate(u,v);
    return merge(s.first,merge(u,t.second));
  }

  decltype(auto) query(Node *&a,size_t l,size_t r){
    auto s=split(a,l);
    auto t=split(s.second,r-l);
    auto u=t.first;
    auto res=static_cast<Impl*>(this)->query(u);
    a=merge(s.first,merge(u,t.second));
    return res;
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T>
struct Array{
  struct Node{
    Node *l,*r,*p;
    size_t cnt;
    bool rev;
    T val;
    Node(T val):
      cnt(1),rev(0),val(val){l=r=p=nullptr;}
  };

  static inline size_t count(const Node *t){
    return t?t->cnt:0;
  }

  inline void toggle(Node *t){
    swap(t->l,t->r);
    t->rev^=1;
  }

  inline bool dirty(Node *t){
    return t->rev;
  }

  inline Node* eval(Node* t){
    if(t->rev){
      if(t->l) toggle(t->l);
      if(t->r) toggle(t->r);
      t->rev=false;
    }
    return t;
  }

  inline Node* pushup(Node *t){
    t->cnt=count(t->l)+1+count(t->r);
    return t;
  }

  inline T reflect(Node *t){
    assert(t);
    return t->val;
  }

  void dump(typename vector<Node>::iterator it,Node* const t,bool rev){
    if(!count(t)) return;

    Node *l=t->l,*r=t->r;
    if(rev) swap(l,r);
    rev^=t->rev;

    dump(it,l,rev);
    *(it+count(l))=Node(t->val);
    dump(it+count(l)+1,r,rev);
  }

  vector<Node> dump(Node* t){
    assert(t!=nullptr);
    vector<Node> vs(count(t),*t);
    dump(vs.begin(),t,false);
    return vs;
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;

#define call_from_test
#include "../rbst.cpp"
#undef call_from_test

#endif
//BEGIN CUT HERE
template<typename Data, size_t LIM>
struct Basic : RBST<Basic<Data, LIM>, Data, typename Data::Node, LIM>{
  using super = RBST<Basic, Data, typename Data::Node, LIM>;
  using Node = typename Data::Node;

  Data data;

  template<class... Args>
  Basic(Args... args):data(forward<Args>(args)...){}

  inline Node* touch(Node *t){return data.eval(t);}

  using super::toggle;
  inline void toggle(Node *t){return data.toggle(t);}
  inline Node* pushup(Node *t){return data.pushup(t);}

  inline decltype(auto) get_val(Node *a,size_t k){
    return data.reflect(super::get_val(a,k));
  }

  using super::query;
  inline decltype(auto) query(Node *a){
    return data.reflect(a);
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,q;
  cin>>n>>q;

  using Data = Array<int>;
  using Node = Data::Node;
  const int LIM = 1e6;
  Basic<Data, LIM> as;

  Node* rt=nullptr;
  vector<Node*> vs(n+1);
  for(int i=0;i<n;i++){
    int a;
    cin>>a;
    a--;
    vs[a]=as.create(a+1);
    rt=as.merge(rt,vs[a]);
  }

  for(int i=0;i<q;i++){
    int p;
    cin>>p;
    p--;
    int k=as.order_of_key(vs[p]);
    auto s=as.split(rt,k);
    auto t=as.split(s.second,1);
    rt=as.merge(as.merge(t.second,t.first),s.first);
  }

  for(int i=0;i<n;i++){
    if(i) cout<<" ";
    cout<<as.get_val(rt,i);
  }
  cout<<endl;
  return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 7912
final_rank: 10

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

template<typename T>
struct List {
    struct Node {
        Node *prev, *next;
        T data;
        Node(Node* prev = nullptr, Node* next = nullptr, T data = T())
        : prev(prev), next(next), data(data) { }
    };
    Node *head, *tail;
    List() : head(new Node()), tail(new Node()) {
        head->next = tail, tail->prev = head;
    }
    Node* begin() { return head->next; }
    Node* end() { return tail; }
    Node* insert(Node* cur, T data) {
        cur = new Node(cur->prev, cur, data);
        return cur->prev->next = cur->next->prev = cur;
    }
    Node* push_front(T data) { return insert(begin(), data); }
    Node* push_back(T data) { return insert(end(), data); }
    Node* erase(Node* cur) {
        if (cur == head || cur == tail) return cur;
        cur->prev->next = cur->next, cur->next->prev = cur->prev;
        Node* tmp = cur->next;
        return free(cur), tmp;
    }
    Node* pop_front() { return erase(begin()); }
    Node* pop_back() { return erase(end()->prev); }
    Node* find(T data) {
        Node* cur = begin();
        while (cur != end() && cur->data != data) cur = cur->next;
        return cur;
    }
    friend ostream& operator<<(ostream& os, List& li) {
        Node* cur = li.begin();
        for (int cnt = 0; cur != li.end(); cur = cur->next) {
            if (cnt++) os << " "; os << cur->data;
        }
        return os;
    }
    Node* swap_by_pivot(Node* cur) {
        if (cur->prev == head && cur->next != tail) {
            cur->next->prev = head;
            tail->prev->next = cur;
            head->next = cur->next;
            cur->prev = tail->prev;
            cur->next = tail;
            tail->prev = cur;
            return cur;
        }
        if (cur->prev != head && cur->next == tail) {
            cur->prev->next = tail;
            head->next->prev = cur;
            tail->prev = cur->prev;
            cur->next = head->next;
            cur->prev = head;
            head->next = cur;
            return cur;
        }
        if (cur->prev != head && cur->next != tail) {
            cur->prev->next = tail;
            cur->next->prev = head;
            tail->prev->next = cur;
            head->next->prev = cur;
            swap(tail->prev, cur->prev);
            swap(head->next, cur->next);
            return cur;
        }
        return cur;
    }
};

int main() {
    List<int> li;
    int n, q; cin >> n >> q;
    vector<List<int>::Node*> pos(n + 1);
    for (int i = 0; i < n; i++) {
        int a; cin >> a;
        pos[a] = li.push_back(a);
    }
    while (q--) {
        int x; cin >> x;
        li.swap_by_pivot(pos[x]);
    }
    cout << li << endl;
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 6760
final_rank: 8

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;

template<typename T>
struct List {
    struct Node {
        Node *prev, *next;
        T data;
        Node(Node* prev = nullptr, Node* next = nullptr, T data = T(0))
        : prev(prev), next(next), data(data) { }
    };
    Node *head, *tail;
    List() : head(new Node()), tail(new Node()) {
        head->next = tail, tail->prev = head;
    }
    Node* begin() { return head->next; }
    Node* end() { return tail; }
    Node* insert(Node* cur, T data) {
        cur = new Node(cur->prev, cur, data);
        return cur->prev->next = cur->next->prev = cur;
    }
    Node* push_front(T data) { return insert(begin(), data); }
    Node* push_back(T data) { return insert(end(), data); }
    Node* erase(Node* cur) {
        if (cur == head || cur == tail) return cur;
        cur->prev->next = cur->next, cur->next->prev = cur->prev;
        Node* tmp = cur->next;
        return free(cur), tmp;
    }
    Node* pop_front() { return erase(begin()); }
    Node* pop_back() { return erase(end()->prev); }
    Node* find(T data) {
        Node* cur = begin();
        while (cur != end() && cur->data != data) cur = cur->next;
        return cur;
    }
    friend ostream& operator<<(ostream& os, List& li) {
        Node* cur = li.begin();
        for (int cnt = 0; cur != li.end(); cur = cur->next) {
            if (cnt++) os << " "; os << cur->data;
        }
        return os;
    }
    Node* pivot_swap(Node* cur) {
        if (cur->prev == head && cur->next != tail) {
            cur->next->prev = head;
            tail->prev->next = cur;
            head->next = cur->next;
            cur->prev = tail->prev;
            cur->next = tail;
            tail->prev = cur;
            return cur;
        }
        if (cur->prev != head && cur->next == tail) {
            cur->prev->next = tail;
            head->next->prev = cur;
            tail->prev = cur->prev;
            cur->next = head->next;
            cur->prev = head;
            head->next = cur;
            return cur;
        }
        if (cur->prev != head && cur->next != tail) {
            cur->prev->next = tail;
            cur->next->prev = head;
            tail->prev->next = cur;
            head->next->prev = cur;
            swap(tail->prev, cur->prev);
            swap(head->next, cur->next);
            return cur;
        }
        return cur;
    }
};

int main() {
    List<int> li;
    int n, q; cin >> n >> q;
    vector<List<int>::Node*> pos(n + 1);
    for (int i = 0; i < n; i++) {
        int a; cin >> a;
        pos[a] = li.push_back(a);
    }
    while (q--) {
        int x; cin >> x;
        assert(pos[x] == li.pivot_swap(pos[x]));
    }
    cout << li << endl;
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 6736
final_rank: 7

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

template<typename T>
struct List {
    struct Node {
        Node *prev, *next;
        T data;
        Node(Node* prev = nullptr, Node* next = nullptr, T data = T(0))
        : prev(prev), next(next), data(data) { }
    };
    Node *head, *tail;
    List() : head(new Node()), tail(new Node()) {
        head->next = tail, tail->prev = head;
    }
    Node* begin() { return head->next; }
    Node* end() { return tail; }
    Node* insert(Node* cur, T data) {
        cur = new Node(cur->prev, cur, data);
        return cur->prev->next = cur->next->prev = cur;
    }
    Node* push_front(T data) { return insert(begin(), data); }
    Node* push_back(T data) { return insert(end(), data); }
    Node* erase(Node* cur) {
        if (cur == head || cur == tail) return cur;
        cur->prev->next = cur->next, cur->next->prev = cur->prev;
        Node* tmp = cur->next;
        return free(cur), tmp;
    }
    Node* pop_front() { return erase(begin()); }
    Node* pop_back() { return erase(end()->prev); }
    Node* find(T data) {
        Node* cur = begin();
        while (cur != end() && cur->data != data) cur = cur->next;
        return cur;
    }
    friend ostream& operator<<(ostream& os, List& li) {
        Node* cur = li.begin();
        for (int cnt = 0; cur != li.end(); cur = cur->next) {
            if (cnt++) os << " "; os << cur->data;
        }
        return os;
    }
    void pivot_swap(Node* cur) {
        if (cur->prev == head) {
            cur->next->prev = head;
            tail->prev->next = cur;
            head->next = cur->next;
            cur->prev = tail->prev;
            cur->next = tail;
            tail->prev = cur;
        } else if (cur->next == tail) {
            cur->prev->next = tail;
            head->next->prev = cur;
            tail->prev = cur->prev;
            cur->next = head->next;
            cur->prev = head;
            head->next = cur;
        } else {
            cur->prev->next = tail;
            cur->next->prev = head;
            tail->prev->next = cur;
            head->next->prev = cur;
            swap(tail->prev, cur->prev);
            swap(head->next, cur->next);
        }
    }
};

int main() {
    List<int> li;
    int n, q; cin >> n >> q;
    vector<List<int>::Node*> pos(n + 1);
    for (int i = 0; i < n; i++) {
        int a; cin >> a;
        pos[a] = li.push_back(a);
    }
    while (q--) {
        int x; cin >> x;
        li.pivot_swap(pos[x]);
    }
    cout << li << endl;
	return 0;
}
accuracy: 0.9142857142857143
time_ms: 40
memory_kb: 6712
final_rank: 18

code_snippet: #include <cstdio>
#include <cstdint>
#include <cstddef>
#include <algorithm>
#include <utility>
#include <memory>
#include <array>

constexpr intmax_t  operator ""_jd(unsigned long long n) { return n; }
constexpr uintmax_t operator ""_ju(unsigned long long n) { return n; }
constexpr size_t    operator ""_zu(unsigned long long n) { return n; }
// constexpr ptrdiff_t operator ""_td(unsigned long long n) { return n; }

template <typename Tp>
class order_statistic_tree {
  // based on splay tree

public:
  using size_type = size_t;
  using difference_type = ptrdiff_t;
  using value_type = Tp;
  using reference = Tp&;
  using const_reference = Tp const&;
  class iterator;
  class const_iterator;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

private:
  class node;
  using pointer = std::shared_ptr<node>;

  class node {
    friend order_statistic_tree;
    friend iterator;
    friend const_iterator;

  public:
    using size_type = size_t;
    using difference_type = ptrdiff_t;
    using value_type = Tp;
    using reference = Tp&;
    using const_reference = Tp const&;

  private:
    using pointer = std::shared_ptr<node>;

    mutable pointer M_parent = nullptr;
    mutable std::array<pointer, 2> M_children{{nullptr, nullptr}};
    value_type M_value;
    mutable size_type M_size = 1;

  public:
    node() = default;
    node(node const&) = delete;  // !
    node(node&&) = default;
    node(const_reference value): M_value(value) {}
    node(value_type&& value): M_value(std::move(value)) {}

    ~node() {
      // if (M_children[0]) delete M_children[0].get();
      // if (M_children[1]) delete M_children[1].get();
    }

    void set_size() const {
      // for splaying
      M_size = 1;
      if (M_children[0]) M_size += M_children[0]->M_size;
      if (M_children[1]) M_size += M_children[1]->M_size;
    }

    size_type left_size() const {
      if (!M_children[0]) return 0;
      return M_children[0]->M_size;
    }
    size_type right_size() const {
      if (!M_children[1]) return 0;
      return M_children[1]->M_size;
    }
  };

  static pointer S_next(pointer ptr, order_statistic_tree* tree,
                        difference_type n = 1) {

    if (n == 0) return ptr;
    if (n < 0) return S_prev(ptr, tree, -n);

    tree->M_root = S_splay(ptr);
    // fprintf(stderr, "null? %d\n", !ptr);
    // if (ptr) fprintf(stderr, "next: %p, size: %zu\n", ptr.get(), ptr->M_size);
    ptr = ptr->M_children[1];
    --n;
    while (ptr) {
      difference_type ls = ptr->left_size();
      if (n == ls) return ptr;
      if (n < ls) {
        ptr = ptr->M_children[0];
      } else {
        ptr = ptr->M_children[1];
        n -= ls+1;
      }
    }
    return nullptr;
  }
  static pointer S_prev(pointer ptr, order_statistic_tree* tree,
                        difference_type n = 1) {

    if (n == 0) return ptr;
    if (n < 0) return S_next(ptr, tree, -n);
    if (!ptr)
      return S_prev(tree->M_rightmost, tree, n-1);  // past-the-end

    tree->M_root = S_splay(ptr);
    ptr = ptr->M_children[0];
    --n;
    while (ptr) {
      difference_type rs = ptr->right_size();
      if (n == rs) return ptr;
      if (n < rs) {
        ptr = ptr->M_children[1];
      } else {
        ptr = ptr->M_children[0];
        n -= rs+1;
      }
    }
    return nullptr;
  }

  static size_type S_index(pointer ptr, order_statistic_tree* tree) {
    if (!ptr) return tree->size();
    tree->M_root = S_splay(ptr);
    return ptr->left_size();
  }

  static size_type S_parent_dir(pointer ptr) {
    if (!ptr->M_parent) return -1_zu;
    if (ptr->M_parent->M_children[0] == ptr) return 0;
    if (ptr->M_parent->M_children[1] == ptr) return 1;
    return -1_zu;
  }

  static pointer S_zig(pointer cur, size_type dir) {
    pointer par = cur->M_parent;
    pointer sub = cur->M_children[!dir];

    cur->M_children[!dir] = par;
    par->M_parent = cur;
    par->M_children[dir] = sub;
    if (sub) sub->M_parent = par;

    par->set_size();
    cur->set_size();
    return cur;
  }
  static pointer S_zigzig(pointer cur, size_type dir) {
    pointer par = cur->M_parent;
    pointer gpar = par->M_parent;
    pointer sub1 = cur->M_children[!dir];
    pointer sub2 = par->M_children[!dir];
    size_type gd = S_parent_dir(gpar);

    cur->M_parent = gpar->M_parent;
    if (gd != -1_zu) cur->M_parent->M_children[gd] = cur;
    cur->M_children[!dir] = par;
    par->M_parent = cur;
    par->M_children[dir] = sub1;
    if (sub1) sub1->M_parent = par;
    par->M_children[!dir] = gpar;
    gpar->M_parent = par;
    gpar->M_children[dir] = sub2;
    if (sub2) sub2->M_parent = gpar;

    gpar->set_size();
    par->set_size();
    cur->set_size();
    return cur;
  }
  static pointer S_zigzag(pointer cur, size_type dir) {
    pointer par = cur->M_parent;
    pointer gpar = par->M_parent;
    pointer sub1 = cur->M_children[dir];
    pointer sub2 = cur->M_children[!dir];
    size_type gd = S_parent_dir(gpar);

    cur->M_parent = gpar->M_parent;
    if (gd != -1_zu) cur->M_parent->M_children[gd] = cur;
    cur->M_children[dir] = gpar;
    gpar->M_parent = cur;
    cur->M_children[!dir] = par;
    par->M_parent = cur;
    gpar->M_children[!dir] = sub1;
    if (sub1) sub1->M_parent = gpar;
    par->M_children[dir] = sub2;
    if (sub2) sub2->M_parent = par;

    gpar->set_size();
    par->set_size();
    cur->set_size();
    return cur;
  }

  static pointer S_splay(pointer ptr) {
    if (!ptr) return nullptr;
    while (true) {
      size_type pd = S_parent_dir(ptr);
      if (pd == -1_zu) return ptr;
      size_type gd = S_parent_dir(ptr->M_parent);
      if (gd == -1_zu) return S_zig(ptr, pd);
      ptr = ((gd == pd)? S_zigzig(ptr, pd): S_zigzag(ptr, pd));
    }
  }

public:
  class iterator {
    friend order_statistic_tree;
    friend const_iterator;

  public:
    using size_type = size_t;
    using difference_type = ptrdiff_t;
    using value_type = Tp;
    using reference = Tp&;
    using const_reference = Tp const&;
    using pointer = std::shared_ptr<node>;
    using iterator_category = std::random_access_iterator_tag;

  private:
    pointer M_ptr = nullptr;
    mutable order_statistic_tree* M_tree = nullptr;

  public:
    iterator() = default;
    iterator(iterator const&) = default;
    iterator(iterator&&) = default;
    iterator(pointer ptr, order_statistic_tree* tree):
      M_ptr(ptr), M_tree(tree) {}

    iterator& operator =(iterator const&) = default;
    iterator& operator =(iterator&&) = default;

    iterator& operator ++() { M_ptr = S_next(M_ptr, M_tree); return *this; }
    iterator& operator --() { M_ptr = S_prev(M_ptr, M_tree); return *this; }

    iterator& operator +=(difference_type n) {
      M_ptr = S_next(M_ptr, M_tree, n); return *this;
    }
    iterator& operator -=(difference_type n) {
      M_ptr = S_prev(M_ptr, M_tree, n); return *this;
    }

    iterator operator ++(int) { iterator tmp(*this); ++*this; return tmp; }
    iterator operator --(int) { iterator tmp(*this); --*this; return tmp; }

    iterator operator +(difference_type n) const {
      return iterator(*this) += n;
    }
    iterator operator -(difference_type n) const {
      return iterator(*this) -= n;
    }

    difference_type operator -(const_iterator const& other) const {
      return S_index(M_ptr, M_tree) - S_index(other.M_ptr, M_tree);
    }

    bool operator ==(const_iterator const& other) const {
      return M_ptr == other.M_ptr;
    }
    bool operator !=(const_iterator const& other) const {
      return !(*this == other);
    }

    bool operator <(const_iterator const& other) const {
      return S_index(M_ptr, M_tree) < S_index(other.M_ptr, M_tree);
    }
    bool operator >(const_iterator const& other) const {
      return other < *this;
    }
    bool operator <=(const_iterator const& other) const {
      return !(other < *this);
    }
    bool operator >=(const_iterator const& other) const {
      return !(*this < other);
    }

    reference operator *() {
      M_tree->M_root = S_splay(M_ptr); return M_ptr->M_value;
    }
    const_reference operator *() const {
      M_tree->M_root = S_splay(M_ptr); return M_ptr->M_value;
    }
  };

public:
  class const_iterator {
    friend order_statistic_tree;
    friend iterator;

  public:
    using size_type = size_t;
    using difference_type = ptrdiff_t;
    using value_type = Tp;
    using reference = Tp const&;
    using const_reference = Tp const&;
    using pointer = std::shared_ptr<node>;
    using iterator_category = std::random_access_iterator_tag;

  private:
    pointer M_ptr = nullptr;
    mutable order_statistic_tree* M_tree = nullptr;

  public:
    const_iterator() = default;
    const_iterator(const_iterator const&) = default;
    const_iterator(const_iterator&&) = default;
    const_iterator(iterator const& other): M_ptr(other.M_ptr) {}
    const_iterator(iterator&& other): M_ptr(other.M_ptr) {}
    const_iterator(pointer ptr, order_statistic_tree* tree):
      M_ptr(ptr), M_tree(tree) {}

    const_iterator& operator =(const_iterator const&) = default;
    const_iterator& operator =(const_iterator&&) = default;
    const_iterator& operator =(iterator const& other) {
      M_ptr = other.M_ptr;
      M_tree = other.M_tree;
      return *this;
    }
    const_iterator& operator =(iterator&& other) {
      M_ptr = other.M_ptr;
      M_tree = other.M_tree;
      return *this;
    }

    const_iterator& operator ++() { M_ptr = S_next(M_ptr, M_tree); return *this; }
    const_iterator& operator --() { M_ptr = S_prev(M_ptr, M_tree); return *this; }

    const_iterator& operator +=(difference_type n) {
      M_ptr = S_next(M_ptr, M_tree, n); return *this;
    }
    const_iterator& operator -=(difference_type n) {
      M_ptr = S_prev(M_ptr, M_tree, n); return *this;
    }

    const_iterator operator ++(int) {
      const_iterator tmp(*this); ++*this; return tmp;
    }
    const_iterator operator --(int) {
      const_iterator tmp(*this); --*this; return tmp;
    }

    const_iterator operator +(difference_type n) const {
      return const_iterator(*this) += n;
    }
    const_iterator operator -(difference_type n) const {
      return const_iterator(*this) -= n;
    }

    difference_type operator -(const_iterator const& other) const {
      return S_index(M_ptr, M_tree) - S_index(other.M_ptr, M_tree);
    }

    bool operator ==(const_iterator const& other) const {
      return M_ptr == other.M_ptr;
    }
    bool operator !=(const_iterator const& other) const {
      return !(*this == other);
    }

    bool operator <(const_iterator const& other) const {
      return S_index(M_ptr, M_tree) < S_index(other.M_ptr, M_tree);
    }
    bool operator >(const_iterator const& other) const {
      return other < *this;
    }
    bool operator <=(const_iterator const& other) const {
      return !(other < *this);
    }
    bool operator >=(const_iterator const& other) const {
      return !(*this < other);
    }

    reference operator *() const {
      M_tree->M_root = S_splay(M_ptr); return M_ptr->M_value;
    }
  };

private:
  size_type M_size = 0;
  pointer M_root = nullptr;
  pointer M_leftmost = nullptr;
  pointer M_rightmost = nullptr;

  void M_init_ends() {
    M_leftmost = M_rightmost = M_root;
    if (!M_root) return;
    while (M_leftmost->M_children[0])
      M_leftmost = M_leftmost->M_children[0];
    while (M_rightmost->M_children[1])
      M_rightmost = M_rightmost->M_children[1];
  }

  static void S_deep_copy(pointer& dst, pointer const& src) {
    dst = std::make_shared<node>(src->M_value);
    for (size_type i = 0; i <= 1; ++i)
      if (src->M_children[i])
        S_deep_copy(dst->M_children[i], src->M_children[i]);
  }

  void M_deep_copy(order_statistic_tree const& other) {
    clear();
    if (!other.M_root) return;

    S_deep_copy(M_root, other.M_root);
    M_size = other.M_size;
    M_init_ends();
  }

  void M_move(order_statistic_tree&& other) {
    clear();
    M_root = other.M_root;
    M_leftmost = other.M_leftmost;
    M_rightmost = other.M_rightmost;
    M_size = other.M_size;
    other.clear();
  }

  explicit order_statistic_tree(pointer root): M_root(root) {
    if (!root) return;
    M_root->set_size();
    M_size = M_root->M_size;
    M_init_ends();
  }

public:
  order_statistic_tree() = default;
  order_statistic_tree(order_statistic_tree const& other) {
    M_deep_copy(other);
  }
  order_statistic_tree(order_statistic_tree&& other) {
    M_move(std::move(other));
  }

  template <typename InputIt>
  order_statistic_tree(InputIt first, InputIt last) { assign(first, last); }
  order_statistic_tree(std::initializer_list<value_type> il) { assign(il); }

  explicit order_statistic_tree(size_type size, const_reference value) {
    assign(size, value);
  }
  explicit order_statistic_tree(size_type size) { assign(size); }

  template <typename InputIt>
  void assign(InputIt first, InputIt last) {
    clear();
    while (first != last) {
      pointer tmp = M_root;
      M_root = std::make_shared<node>(*first++);
      M_root->M_children[0] = tmp;
      M_root->M_size = ++M_size;
      if (tmp) tmp->M_parent = M_root;
    }
    M_init_ends();
  }
  void assign(std::initializer_list<value_type> il) {
    assign(il.begin(), il.end());
  }

  void assign(size_type size, const_reference value) {
    clear();
    for (size_type i = 0; i < size; ++i) {
      pointer tmp = M_root;
      M_root = std::make_shared<node>(value);
      M_root->M_children[0] = tmp;
      M_root->M_size = ++M_size;
      if (tmp) tmp->M_parent = M_root;
    }
    M_init_ends();
  }
  void assign(size_type size) {
    clear();
    for (size_type i = 0; i < size; ++i) {
      pointer tmp = M_root;
      M_root = std::make_shared<node>();
      M_root->M_children[0] = tmp;
      M_root->M_size = ++M_size;
      if (tmp) tmp->M_parent = M_root;
    }
    M_init_ends();
  }

  void clear() {
    M_size = 0;
    M_root = M_leftmost = M_rightmost = nullptr;
  }

  order_statistic_tree& operator =(order_statistic_tree const& other) {
    M_deep_copy(other);
    return *this;
  }
  order_statistic_tree& operator =(order_statistic_tree&& other) {
    M_move(std::move(other));
    return *this;
  }

  reference at(size_type n) {
    if (n >= size()) throw std::out_of_range("n >= size()");
    return *(begin() + n);
  }
  const_reference at(size_type n) const {
    if (n >= size()) throw std::out_of_range("n >= size()");
    return *(begin() + n);
  }

  reference operator [](size_type n) { return *(begin() + n); }
  const_reference operator [](size_type n) const { return *(begin() + n); }

  reference front() { return *begin(); }
  const_reference front() const { *begin(); }
  reference back() { return *rbegin(); }
  const_reference back() const { *rbegin(); }

  iterator begin() { return iterator(M_leftmost, this); }
  const_reference begin() const { return const_reference(M_leftmost, this); }
  const_reference cbegin() const { return const_reference(M_leftmost, this); }

  iterator end() { return iterator(nullptr, this); }
  const_reference end() const { return const_reference(nullptr, this); }
  const_reference cend() const { return const_reference(nullptr, this); }

  reverse_iterator rbegin() { return end(); }
  const_reverse_iterator rbegin() const { return end(); }
  const_reverse_iterator crbegin() const { return cend(); }

  reverse_iterator rend() { return begin(); }
  const_reverse_iterator rend() const { return begin(); }
  const_reverse_iterator crend() const { return cbegin(); }

  bool empty() const noexcept { return M_size == 0; }
  size_type size() const { return M_size; }

  iterator insert(const_iterator pos, const_reference value) {
    M_root = S_splay(pos.M_ptr);
    order_statistic_tree tmp = split(pos);
    // fprintf(stderr, "split [%zu]:[%zu]\n", size(), tmp.size());
    iterator res = push_back(value);
    // fprintf(stderr, "inserted [%zu]:[%zu]\n", size(), tmp.size());
    merge(std::move(tmp));
    // fprintf(stderr, "begin(): %p\n", begin().M_ptr.get());
    return res;
  }

  iterator insert(const_iterator pos, value_type&& value) {
    M_root = S_splay(pos.M_ptr);
    order_statistic_tree tmp = split(pos);
    iterator res = push_back(std::move(value));
    merge(std::move(tmp));
    return res;
  }

  iterator insert(const_iterator pos, size_type count, const_reference value) {
    if (count == 0) return pos;
    M_root = S_splay(pos.M_ptr);
    order_statistic_tree tmp = split(pos);
    iterator res = push_back(value);
    for (size_type i = 1; i < count; ++i) push_back(value);
    merge(std::move(tmp));
    return res;
  }

  template <typename InputIt>
  iterator insert(const_iterator pos, InputIt first, InputIt last) {
    if (first == last) return pos;
    M_root = S_splay(pos.M_ptr);
    order_statistic_tree tmp = split(pos);
    iterator res = push_back(*first++);
    while (first != last) push_back(*first++);
    merge(std::move(tmp));
    return res;
  }

  iterator insert(const_iterator pos, std::initializer_list<value_type> il) {
    return insert(pos, il.begin(), il.end());
  }

  template <typename... Args>
  iterator emplace(const_iterator pos, Args&&... args) {
    M_root = S_splay(pos.M_ptr);
    order_statistic_tree tmp = split(pos);
    iterator res = emplace_back(std::forward<Args>(args)...);
    merge(std::move(tmp));
    return res;    
  }

  iterator push_back(const_reference value) {
    M_root = S_splay(M_rightmost);
    pointer tmp = std::make_shared<node>(value);
    tmp->M_children[0] = M_root;
    tmp->M_size = ++M_size;
    if (M_root) M_root->M_parent = tmp;
    if (!M_leftmost) M_leftmost = tmp;
    M_root = M_rightmost = tmp;
    return iterator(tmp, this);
  }

  iterator push_back(value_type&& value) {
    M_root = S_splay(M_rightmost);
    pointer tmp = std::make_shared<node>(std::move(value));
    tmp->M_children[0] = M_root;
    tmp->M_size = ++M_size;
    if (M_root) M_root->M_parent = tmp;
    if (!M_leftmost) M_leftmost = tmp;
    M_root = M_rightmost = tmp;
    return iterator(tmp, this);
  }

  template <typename... Args>
  iterator emplace_back(Args&&... args) {
    M_root = S_splay(M_rightmost);
    pointer tmp = std::make_shared<node>(std::forward<Args>(args)...);
    tmp->M_children[0] = M_root;
    tmp->M_size = ++M_size;
    if (M_root) M_root->M_parent = tmp;
    if (!M_leftmost) M_leftmost = tmp;
    M_root = M_rightmost = tmp;
    return iterator(tmp, this);
  }

  iterator push_front(const_reference value) {
    M_root = S_splay(M_leftmost);
    pointer tmp = std::make_shared<node>(value);
    tmp->M_children[1] = M_root;
    tmp->M_size = ++M_size;
    if (M_root) M_root->M_parent = tmp;
    if (!M_rightmost) M_rightmost = tmp;
    M_root = M_leftmost = tmp;
    return iterator(tmp, this);
  }

  iterator push_front(value_type&& value) {
    M_root = S_splay(M_leftmost);
    pointer tmp = std::make_shared<node>(std::move(value));
    tmp->M_children[1] = M_root;
    tmp->M_size = ++M_size;
    if (M_root) M_root->M_parent = tmp;
    if (!M_rightmost) M_rightmost = tmp;
    M_root = M_leftmost = tmp;
    return iterator(tmp, this);
  }

  template <typename... Args>
  iterator emplace_front(Args&&... args) {
    M_root = S_splay(M_leftmost);
    pointer tmp = std::make_shared<node>(std::forward<Args>(args)...);
    tmp->M_children[1] = M_root;
    tmp->M_size = ++M_size;
    if (M_root) M_root->M_parent = tmp;
    if (!M_rightmost) M_rightmost = tmp;
    M_root = M_leftmost = tmp;
    return iterator(tmp, this);
  }

  void pop_back() {
    M_root = S_splay(M_rightmost);
    M_root = M_rightmost->M_children[0];
    if (M_root) M_root->M_parent = nullptr;
    M_rightmost->M_children[0] = nullptr;
    M_init_ends();
    --M_size;
  }

  void pop_front() {
    // fprintf(stderr, "pop_front(), size(): %zu\n", size());
    M_root = S_splay(M_leftmost);
    M_root = M_leftmost->M_children[1];
    if (M_root) M_root->M_parent = nullptr;
    M_leftmost->M_children[1] = nullptr;
    M_init_ends();
    --M_size;
  }

  iterator erase(const_iterator pos) {
    order_statistic_tree tmp = split(pos);
    tmp.pop_front();
    auto res = tmp.begin();
    merge(std::move(tmp));
    return res;
  }

  iterator erase(const_iterator first, const_iterator last) {
    if (first == last) return first;
    order_statistic_tree tmp = split(last);
    split(first);  // discard
    auto res = tmp.begin();
    merge(std::move(tmp));
    return res;
  }

  iterator merge(order_statistic_tree& other) {
    return merge(std::move(other));
  }

  iterator merge(order_statistic_tree&& other) {
    if (other.empty()) return end();
    if (empty()) {
      M_move(std::move(other));
      return begin();
    }
    M_root = S_splay(M_rightmost);
    M_root->M_children[1] = other.M_root;
    other.M_root->M_parent = M_root;
    M_size = (M_root->M_size += other.M_size);
    M_rightmost = other.M_rightmost;
    iterator res(other.M_leftmost, this);
    other.clear();  // not destruct nodes
    return res;
  }

  order_statistic_tree split(const_iterator pos) {
    if (pos == end()) return {};
    if (pos == begin()) return std::move(*this);
    M_root = S_splay(pos.M_ptr);
    // fprintf(stderr, "split: %p %zu\n", M_root.get(), M_root->M_size);
    pointer res = M_root;
    M_root = res->M_children[0];
    res->M_children[0] = nullptr;
    if (M_root) {
      M_root->M_parent = nullptr;
      M_root->set_size();
      M_size = M_root->M_size;
    } else {
      M_size = 0;
    }
    M_init_ends();
    return order_statistic_tree(res);
  }

  template <typename Predicate>
  iterator partition_point(Predicate pred) {
    pointer cur = M_root;
    if (!cur) return end();
    // ... true false ...
    //          ^
    while (true) {
      pointer tmp = cur->M_children[pred(cur->M_value)];
      if (!tmp) break;
      cur = tmp;
    }
    if (pred(cur->M_value)) cur = S_next(cur, this);
    M_root = S_splay(cur);
    return iterator(M_root, this);
  }
};

int arc033_c() {
  size_t q;
  scanf("%zu", &q);

  order_statistic_tree<int> ost;
  for (size_t i = 0; i < q; ++i) {
    int t;
    scanf("%d", &t);

    if (t == 1) {
      int x;
      scanf("%d", &x);
      ost.insert(ost.partition_point([x](int y) { return y < x; }), x);
    } else if (t == 2) {
      ptrdiff_t x;
      scanf("%td", &x);
      --x;
      auto it = ost.begin() + x;
      printf("%d\n", *it);
      ost.erase(it);
    }

    fprintf(stderr, "size: %zu\n", ost.size());
    for (auto it = ost.begin(); it != ost.end(); ++it)
      fprintf(stderr, "%d%c", *it, (std::next(it) != ost.end())? ' ': '\n');
  }
  return 0;
}

#include <vector>
#include <numeric>

int aoj2890() {
  size_t n, q;
  scanf("%zu %zu", &n, &q);

  std::vector<int> a(n);
  for (auto& ai: a) scanf("%d", &ai), --ai;
  order_statistic_tree<int> ost(a.begin(), a.end());

  std::vector<typename order_statistic_tree<int>::const_iterator> its(n);
  {
    for (auto it = ost.begin(); it != ost.end(); ++it)
      its[*it] = it;
  }

  for (size_t i = 0; i < q; ++i) {
    size_t j;
    scanf("%zu", &j);
    --j;

    auto center = ost.split(its[j]);
    auto right = center.split(++center.begin());
    center.merge(ost);
    right.merge(center);
    ost = std::move(right);

    // for (auto it = ost.begin(); it != ost.end(); ++it)
    //   fprintf(stderr, "(%d)%c", *it+1, (std::next(it)!=ost.end())? ' ': '\n');
  }

  for (auto it = ost.begin(); it != ost.end(); ++it)
    printf("%d%c", *it+1, (std::next(it)!=ost.end())? ' ': '\n');

  return 0;
}

int main() {
  aoj2890();
}
accuracy: 1
time_ms: 210
memory_kb: 14536
final_rank: 13

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "functional"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-8;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

int nx[120000];
int bf[120000];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> N >> K;
	vector<int>v(N);
	for (auto &i : v)cin >> i;
	for (int i = 1; i <= N; i++)nx[i] = nx[i] = -1;
	for (int i = 1; i < N; i++) {
		bf[v[i]] = v[i - 1];
	}
	for (int i = 0; i < N - 1; i++) {
		nx[v[i]] = v[i + 1];
	}
	int tp = v[0];
	int bk = v.back();
	while (K--) {
		cin >> M;
		if (M == tp && M == bk) {
			continue;
		}
		else if (M == tp) {
			bf[nx[M]] = -1;
			tp = nx[M];
			nx[bk] = M;
			nx[M] = -1;
			bf[M] = bk;
			bk = M;
		}
		else if (M == bk) {
			nx[bf[M]] = -1;
			bk = bf[M];
			bf[tp] = M;
			bf[M] = -1;
			nx[M] = tp;
			tp = M;
		}
		else {
			nx[bf[M]] = -1;
			bf[nx[M]] = -1;
			nx[bk] = M;
			bf[tp] = M;
			int ntp = nx[M];
			int nbk = bf[M];
			nx[M] = tp;
			bf[M] = bk;
			tp = ntp;
			bk = nbk;
		}
	}
	vector<int>ans;
	int cn = tp;
	ans.push_back(cn);
	while (cn!=bk) {
		cn = nx[cn];
		ans.push_back(cn);
	}
	for (int i = 0; i < N; i++) {
		if (i)cout << " ";
		cout << ans[i];
	}
	cout << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 4680
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
#endif
//BEGIN CUT HERE
template<typename Node, size_t LIM>
struct BBSTBase{
  using u32 = uint32_t;
  u32 xor128(){
    static u32 x = 123456789;
    static u32 y = 362436069;
    static u32 z = 521288629;
    static u32 w = 88675123;

    u32 t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  }

  array<Node, LIM> pool;
  size_t ptr;
  BBSTBase():ptr(0){}

  size_t count(const Node *a){
    return a?a->cnt:0;
  }

  inline Node* create(){
    return &pool[ptr++];
  }

  template<typename T>
  inline Node* create(T v){
    return &(pool[ptr++]=Node(v));
  }

  virtual void toggle(Node *a)=0;
  virtual Node* eval(Node* a)=0;
  virtual Node* recalc(Node* a)=0;

  Node* toggle(Node *a,size_t l,size_t r){
    auto s=split(a,l);
    auto t=split(s.second,r-l);
    auto u=eval(t.first);
    toggle(u);
    return merge(s.first,merge(u,t.second));
  }

  Node* merge(Node* a,Node* b){
    if(a==nullptr) return b;
    if(b==nullptr) return a;
    if(xor128()%(count(a)+count(b))<count(a)){
      a=eval(a);
      a->r=merge(a->r,b);
      a->r->p=a;
      return recalc(a);
    }
    b=eval(b);
    b->l=merge(a,b->l);
    b->l->p=b;
    return recalc(b);
  }

  pair<Node*, Node*> split(Node* a,size_t k){
    if(a==nullptr) return make_pair(a,a);
    a=eval(a);
    if(k<=count(a->l)){
      if(a->l) a->l->p=nullptr;
      auto s=split(a->l,k);
      a->l=s.second;
      if(a->l) a->l->p=a;
      return make_pair(s.first,recalc(a));
    }
    if(a->r) a->r->p=nullptr;
    auto s=split(a->r,k-(count(a->l)+1));
    a->r=s.first;
    if(a->r) a->r->p=a;
    return make_pair(recalc(a),s.second);
  }

  template<typename T>
  Node* insert(Node *a,size_t pos,T v){
    Node* b=create(v);
    auto s=split(a,pos);
    return a=merge(merge(s.first,b),s.second);
  }

  Node* erase(Node *a,size_t pos){
    auto s=split(a,pos);
    auto t=split(s.second,1);
    return merge(s.first,t.second);
  }

  Node* find_by_order(Node *a,size_t k){
    assert(k<count(a));
    a=eval(a);
    size_t num=count(a->l);
    if(k<num) return find_by_order(a->l,k);
    if(k>num) return find_by_order(a->r,k-(num+1));
    return a;
  }

  template<typename T>
  Node* build(size_t l,size_t r,const vector<T> &vs){
    if(l+1==r) return create(vs[l]);
    size_t m=(l+r)>>1;
    return merge(build(l,m,vs),build(m,r,vs));
  }

  template<typename T>
  Node* build(const vector<T> &vs){
    return build(0,vs.size(),vs);
  }
};

template<typename Node, size_t LIM>
struct Array : BBSTBase<Node, LIM>{
  using T = typename Node::T;
  using super = BBSTBase<Node, LIM>;
  Array():super(){}

  using super::count;

  Node* recalc(Node *a){
    a->cnt=count(a->l)+1+count(a->r);
    return a;
  }

  void toggle(Node *a){
    swap(a->l,a->r);
    a->rev^=1;
  }

  // remove "virtual" for optimization
  virtual Node* eval(Node* a){
    if(a->rev){
      if(a->l) toggle(a->l);
      if(a->r) toggle(a->r);
      a->rev=false;
    }
    return recalc(a);
  }

  using super::find_by_order;

  Node* set_val(Node *a,size_t k,T val){
    auto b=find_by_order(a,k);
    b->val=val;
    return b;
  }

  T get_val(Node *a,size_t k){
    return find_by_order(a,k)->val;
  }

  inline bool is_right(Node* a){
    return a->p&&a->p->r==a;
  }

  size_t order_of_key(Node* a){
    size_t res=count(a->l);
    while(a){
      if(is_right(a)) res+=count(a->p->l)+1;
      a=a->p;
    }
    return res;
  }

  void dump(Node* a,typename vector<T>::iterator it){
    if(!count(a)) return;
    if(a->rev){
      if(a->l) toggle(a->l);
      if(a->r) toggle(a->r);
      a->rev=false;
    }
    dump(a->l,it);
    *(it+count(a->l))=a->val;
    dump(a->r,it+count(a->l)+1);
  }

  vector<T> dump(Node* a){
    vector<T> vs(count(a));
    dump(a,vs.begin());
    return vs;
  }
};
template<typename Tp>
struct NodeBase{
  using T = Tp;
  NodeBase *p,*l,*r;
  size_t cnt;
  bool rev;
  T val;
  NodeBase():cnt(0),rev(0){p=l=r=nullptr;}
  NodeBase(T val):
    cnt(1),rev(0),val(val){p=l=r=nullptr;}
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  int n,q;
  cin>>n>>q;
  using Node = NodeBase<int>;
  const int LIM = 1e6;
  Array<Node, LIM> as;

  Node* rt=nullptr;
  vector<Node*> vs(n+1);
  for(int i=0;i<n;i++){
    int a;
    cin>>a;
    a--;
    vs[a]=as.create(a+1);
    rt=as.merge(rt,vs[a]);
  }

  for(int i=0;i<q;i++){
    int p;
    cin>>p;
    p--;
    int k=as.order_of_key(vs[p]);
    auto s=as.split(rt,k);
    auto t=as.split(s.second,1);
    rt=as.merge(as.merge(t.second,t.first),s.first);
  }

  for(int i=0;i<n;i++){
    if(i) cout<<" ";
    cout<<as.get_val(rt,i);
  }
  cout<<endl;
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 42700
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
#endif
//BEGIN CUT HERE
template<typename Node>
struct BBSTBase{
  using u32 = uint32_t;
  u32 xor128(){
    static u32 x = 123456789;
    static u32 y = 362436069;
    static u32 z = 521288629;
    static u32 w = 88675123;

    u32 t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  }

  vector<Node> pool;
  size_t ptr;
  BBSTBase(size_t LIM):pool(LIM),ptr(0){}

  size_t count(const Node *a){
    return a?a->cnt:0;
  }

  inline Node* create(){
    return &pool[ptr++];
  }

  template<typename T>
  inline Node* create(T v){
    return &(pool[ptr++]=Node(v));
  }

  virtual void toggle(Node *a)=0;
  virtual Node* eval(Node* a)=0;
  virtual Node* recalc(Node* a)=0;

  Node* toggle(Node *a,size_t l,size_t r){
    auto s=split(a,l);
    auto t=split(s.second,r-l);
    auto u=eval(t.first);
    toggle(u);
    return merge(s.first,merge(u,t.second));
  }

  Node* merge(Node* a,Node* b){
    if(a==nullptr) return b;
    if(b==nullptr) return a;
    if(xor128()%(count(a)+count(b))<count(a)){
      a=eval(a);
      a->r=merge(a->r,b);
      a->r->p=a;
      return recalc(a);
    }
    b=eval(b);
    b->l=merge(a,b->l);
    b->l->p=b;
    return recalc(b);
  }

  pair<Node*, Node*> split(Node* a,size_t k){
    if(a==nullptr) return make_pair(a,a);
    a=eval(a);
    if(k<=count(a->l)){
      if(a->l) a->l->p=nullptr;
      auto s=split(a->l,k);
      a->l=s.second;
      if(a->l) a->l->p=a;
      return make_pair(s.first,recalc(a));
    }
    if(a->r) a->r->p=nullptr;
    auto s=split(a->r,k-(count(a->l)+1));
    a->r=s.first;
    if(a->r) a->r->p=a;
    return make_pair(recalc(a),s.second);
  }

  template<typename T>
  Node* insert(Node *a,size_t pos,T v){
    Node* b=create(v);
    auto s=split(a,pos);
    return a=merge(merge(s.first,b),s.second);
  }

  Node* erase(Node *a,size_t pos){
    auto s=split(a,pos);
    auto t=split(s.second,1);
    return merge(s.first,t.second);
  }

  Node* find_by_order(Node *a,size_t k){
    assert(k<count(a));
    a=eval(a);
    size_t num=count(a->l);
    if(k<num) return find_by_order(a->l,k);
    if(k>num) return find_by_order(a->r,k-(num+1));
    return a;
  }
};

template<typename Node>
struct Array : BBSTBase<Node>{
  using T = typename Node::T;

  static constexpr size_t LIM = 1e6;
  Array():BBSTBase<Node>(LIM){}

  Node* build(size_t l,size_t r,const vector<T> &vs){
    if(l+1==r) return create(vs[l]);
    size_t m=(l+r)>>1;
    return merge(build(l,m,vs),build(m,r,vs));
  }

  Node* build(const vector<T> &vs){
    return build(0,vs.size(),vs);
  }

  using BBSTBase<Node>::count;

  Node* recalc(Node *a){
    a->cnt=count(a->l)+1+count(a->r);
    return a;
  }

  void toggle(Node *a){
    swap(a->l,a->r);
    a->rev^=1;
  }

  // remove "virtual" for optimization
  virtual Node* eval(Node* a){
    if(a->rev){
      if(a->l) toggle(a->l);
      if(a->r) toggle(a->r);
      a->rev=false;
    }
    return recalc(a);
  }

  using BBSTBase<Node>::find_by_order;

  Node* set_val(Node *a,size_t k,T val){
    auto b=find_by_order(a,k);
    b->val=val;
    return b;
  }

  T get_val(Node *a,size_t k){
    return find_by_order(a,k)->val;
  }

  inline bool is_right(Node* a){
    return a->p&&a->p->r==a;
  }

  size_t order_of_key(Node* a){
    size_t res=count(a->l);
    while(a){
      if(is_right(a)) res+=count(a->p->l)+1;
      a=a->p;
    }
    return res;
  }

  void dump(Node* a,typename vector<T>::iterator it){
    if(!count(a)) return;
    if(a->rev){
      if(a->l) toggle(a->l);
      if(a->r) toggle(a->r);
      a->rev=false;
    }
    dump(a->l,it);
    *(it+count(a->l))=a->val;
    dump(a->r,it+count(a->l)+1);
  }

  vector<T> dump(Node* a){
    vector<T> vs(count(a));
    dump(a,vs.begin());
    return vs;
  }
};
template<typename Tp>
struct NodeBase{
  using T = Tp;
  NodeBase *p,*l,*r;
  size_t cnt;
  bool rev;
  T val;
  NodeBase():cnt(0),rev(0){p=l=r=nullptr;}
  NodeBase(T val):
    cnt(1),rev(0),val(val){p=l=r=nullptr;}
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  int n,q;
  cin>>n>>q;
  using Node = NodeBase<int>;
  Array<Node> as;

  Node* rt=nullptr;
  vector<Node*> vs(n+1);
  for(int i=0;i<n;i++){
    int a;
    cin>>a;
    a--;
    vs[a]=as.create(a+1);
    rt=as.merge(rt,vs[a]);
  }

  for(int i=0;i<q;i++){
    int p;
    cin>>p;
    p--;
    int k=as.order_of_key(vs[p]);
    auto s=as.split(rt,k);
    auto t=as.split(s.second,1);
    rt=as.merge(as.merge(t.second,t.first),s.first);
  }

  for(int i=0;i<n;i++){
    if(i) cout<<" ";
    cout<<as.get_val(rt,i);
  }
  cout<<endl;
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 42632
final_rank: 15

code_snippet: #ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
#endif
//BEGIN CUT HERE
template<typename T>
struct Array{
  using u32 = uint32_t;
  u32 xor128(){
    static u32 x = 123456789;
    static u32 y = 362436069;
    static u32 z = 521288629;
    static u32 w = 88675123;

    u32 t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  }

  struct Node{
    Node *p,*l,*r;
    size_t cnt;
    bool rev;
    T val;
    Node():cnt(0),rev(0){p=l=r=nullptr;}
    Node(T val):
      cnt(1),rev(0),val(val){p=l=r=nullptr;}
  };

  const size_t LIM = 1e6;
  vector<Node> pool;
  size_t ptr;

  Array():pool(LIM),ptr(0){}

  Node* build(size_t l,size_t r,const vector<T> &vs){
    if(l+1==r) return create(vs[l]);
    size_t m=(l+r)>>1;
    return merge(build(l,m,vs),build(m,r,vs));
  }

  Node* build(const vector<T> &vs){
    return build(0,vs.size(),vs);
  }

  inline Node* create(){
    return &pool[ptr++];
  }

  inline Node* create(T v){
    return &(pool[ptr++]=Node(v));
  }

  size_t count(const Node *a){
    return a?a->cnt:0;
  }

  Node* recalc(Node *a){
    a->cnt=count(a->l)+1+count(a->r);
    return a;
  }

  void toggle(Node *a){
    swap(a->l,a->r);
    a->rev^=1;
  }

  // remove "virtual" for optimization
  virtual Node* eval(Node* a){
    if(a->rev){
      if(a->l) toggle(a->l);
      if(a->r) toggle(a->r);
      a->rev=false;
    }
    return recalc(a);
  }

  pair<Node*, Node*> split(Node* a,size_t k){
    if(a==nullptr) return make_pair(a,a);
    a=eval(a);
    if(k<=count(a->l)){
      if(a->l) a->l->p=nullptr;
      auto s=split(a->l,k);
      a->l=s.second;
      if(a->l) a->l->p=a;
      return make_pair(s.first,recalc(a));
    }
    if(a->r) a->r->p=nullptr;
    auto s=split(a->r,k-(count(a->l)+1));
    a->r=s.first;
    if(a->r) a->r->p=a;
    return make_pair(recalc(a),s.second);
  }

  Node* merge(Node* a,Node* b){
    if(a==nullptr) return b;
    if(b==nullptr) return a;
    if(xor128()%(count(a)+count(b))<count(a)){
      a=eval(a);
      a->r=merge(a->r,b);
      a->r->p=a;
      return recalc(a);
    }
    b=eval(b);
    b->l=merge(a,b->l);
    b->l->p=b;
    return recalc(b);
  }

  Node* insert(Node *a,size_t pos,T v){
    Node* b=create(v);
    auto s=split(a,pos);
    return a=merge(merge(s.first,b),s.second);
  }

  Node* erase(Node *a,size_t pos){
    auto s=split(a,pos);
    auto t=split(s.second,1);
    return merge(s.first,t.second);
  }

  Node* toggle(Node *a,size_t l,size_t r){
    auto s=split(a,l);
    auto t=split(s.second,r-l);
    auto u=eval(t.first);
    toggle(u);
    return merge(s.first,merge(u,t.second));
  }

  Node* find_by_order(Node *a,size_t k){
    assert(k<count(a));
    a=eval(a);
    size_t num=count(a->l);
    if(k<num) return find_by_order(a->l,k);
    if(k>num) return find_by_order(a->r,k-(num+1));
    return a;
  }

  Node* set_val(Node *a,size_t k,T val){
    auto b=find_by_order(a,k);
    b->val=val;
  }

  T get_val(Node *a,size_t k){
    return find_by_order(a,k)->val;
  }

  inline bool is_right(Node* a){
    return a->p&&a->p->r==a;
  }

  size_t order_of_key(Node* a){
    size_t res=count(a->l);
    while(a){
      if(is_right(a)) res+=count(a->p->l)+1;
      a=a->p;
    }
    return res;
  }

  void dump(Node* a,typename vector<T>::iterator it){
    if(!count(a)) return;
    a=eval(a);
    dump(a->l,it);
    *(it+count(a->l))=a->val;
    dump(a->r,it+count(a->l)+1);
  }

  vector<T> dump(Node* a){
    vector<T> vs(count(a));
    dump(a,vs.begin());
    return vs;
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  int n,q;
  cin>>n>>q;
  Array<int> as;
  using Node = decltype(as)::Node;

  Node* rt=nullptr;
  vector<Node*> vs(n+1);
  for(int i=0;i<n;i++){
    int a;
    cin>>a;
    a--;
    vs[a]=as.create(a+1);
    rt=as.merge(rt,vs[a]);
  }

  for(int i=0;i<q;i++){
    int p;
    cin>>p;
    p--;
    int k=as.order_of_key(vs[p]);
    auto s=as.split(rt,k);
    auto t=as.split(s.second,1);
    rt=as.merge(as.merge(t.second,t.first),s.first);
  }

  for(int i=0;i<n;i++){
    if(i) cout<<" ";
    cout<<as.get_val(rt,i);
  }
  cout<<endl;
  return 0;
}
#endif
accuracy: 1
time_ms: 130
memory_kb: 42700
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
//INSERT ABOVE HERE
signed main(){
  Int n,q;
  cin>>n>>q;
  vector<Int> A(n),B(q);
  for(Int i=0;i<n;i++) cin>>A[i];
  for(Int i=0;i<q;i++) cin>>B[i];
  
  if(n==1){
    cout<<1<<endl;
    return 0;
  }

  vector<Int> L(n+1,0),R(n+1,0);
  for(Int i=0;i+1<n;i++){
    R[A[i]]=A[i+1];
    L[A[i+1]]=A[i];
  }
  Int lm=A[0],rm=A[n-1];

  for(Int i=0;i<q;i++){
    Int x=B[i];
    if(x==rm){
      Int l=L[x];

      R[l]=0;
      L[x]=0;
      R[x]=lm;
      L[lm]=x;

      lm = x;
      rm = l;
    }else if(x==lm){
      Int r=R[x]; 

      L[r]=0;
      R[x]=0;
      L[x]=rm;
      R[rm]=x;
      
      lm = r;
      rm = x;
    }else{
      Int l=L[x],r=R[x];
      L[x]=rm;
      R[x]=lm;

      R[l]=0;
      L[r]=0;

      L[lm]=x;
      R[rm]=x;

      rm=l;
      lm=r;
    }    
  }
  
  vector<Int> ans;
  while(lm!=0){
    ans.emplace_back(lm);
    lm=R[lm];
  }
  for(Int i=0;i<n;i++){
    if(i) cout<<" ";
    cout<<ans[i];
  }
  cout<<endl;
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 6872
final_rank: 9

code_snippet: #include "bits/stdc++.h"

using namespace std;

using ll = long long;
using ld = long double;

const double PI = 3.1415926535897932384626433832795;
const ll MOD = 1000000007;

const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { -1, 0, 1, 0 };

int gcd(int x, int y) { return y ? gcd(y, x % y) : abs(x); }
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : abs(x); }
int lcm(int x, int y) { return x / gcd(x, y) * y; }
ll lcm(ll x, ll y) { return x / gcd(x, y) * y; }

// 解説をﾁｮｯﾄﾐﾀ(ゆるして)

struct node {
	int val;
	node *left, *right;
	node() : val(-1), left(NULL), right(NULL) {}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n, q;
	cin >> n >> q;

	vector<int> a(n);
	for (auto &v : a) {
		cin >> v;
		v--;
	}

	vector<node*> nodes(n);
	for (int i = 0; i < n; i++) {
		nodes[i] = new node();
	}

	node *head = new node();
	node *tail = new node();

	for (int i = 0; i < n; i++) {
		if (i > 0) {
			nodes[a[i]]->left = nodes[a[i - 1]];
		} else {
			head = nodes[a[i]];
		}

		if (i + 1 < n) {
			nodes[a[i]]->right = nodes[a[i + 1]];
		} else {
			tail = nodes[a[i]];
		}

		nodes[a[i]]->val = a[i];
	}

	for (int i = 0; i < q; i++) {
		int query;
		cin >> query;
		query--;

		if (nodes[query] == head) {
			nodes[query]->left = tail;
			tail->right = nodes[query];

			nodes[query]->right->left = NULL;

			head = nodes[query]->right;
			nodes[query]->right = NULL;
			tail = nodes[query];
		} else if (nodes[query] == tail) {
			nodes[query]->right = head;
			head->left = nodes[query];

			nodes[query]->left->right = NULL;

			tail = nodes[query]->left;
			nodes[query]->left = NULL;
			head = nodes[query];
		} else {
			nodes[query]->left->right = NULL;
			swap(nodes[query]->left, tail);
			nodes[query]->left->right = nodes[query];

			nodes[query]->right->left = NULL;
			swap(nodes[query]->right, head);
			nodes[query]->right->left = nodes[query];
		}
	}

	node* cur = head;
	while (cur != NULL) {
		cout << cur->val + 1;
		if (cur->right) cout << " ";
		cur = cur->right;
	}
	cout << endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7040
final_rank: 5

code_snippet: #include "bits/stdc++.h"

using namespace std;

using ll = long long;
using ld = long double;

const double PI = 3.1415926535897932384626433832795;
const ll MOD = 1000000007;

const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { -1, 0, 1, 0 };

int gcd(int x, int y) { return y ? gcd(y, x % y) : abs(x); }
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : abs(x); }
int lcm(int x, int y) { return x / gcd(x, y) * y; }
ll lcm(ll x, ll y) { return x / gcd(x, y) * y; }

struct node {
	int val;
	node *left, *right;
	node() : val(-1), left(NULL), right(NULL) {}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n, q;
	cin >> n >> q;

	vector<int> a(n);
	for (auto &v : a) {
		cin >> v;
		v--;
	}

	vector<node*> nodes(n);
	for (int i = 0; i < n; i++) {
		nodes[i] = new node();
	}

	node *head = new node();
	node *tail = new node();

	for (int i = 0; i < n; i++) {
		if (i > 0) {
			nodes[a[i]]->left = nodes[a[i - 1]];
		} else {
			head = nodes[a[i]];
		}

		if (i + 1 < n) {
			nodes[a[i]]->right = nodes[a[i + 1]];
		} else {
			tail = nodes[a[i]];
		}

		nodes[a[i]]->val = a[i];
	}

	for (int i = 0; i < q; i++) {
		int query;
		cin >> query;
		query--;

		if (nodes[query] == head) {
			nodes[query]->left = tail;
			tail->right = nodes[query];

			nodes[query]->right->left = NULL;

			head = nodes[query]->right;
			nodes[query]->right = NULL;
			tail = nodes[query];
		} else if (nodes[query] == tail) {
			nodes[query]->right = head;
			head->left = nodes[query];

			nodes[query]->left->right = NULL;

			tail = nodes[query]->left;
			nodes[query]->left = NULL;
			head = nodes[query];
		} else {
			nodes[query]->left->right = NULL;
			swap(nodes[query]->left, tail);
			nodes[query]->left->right = nodes[query];

			nodes[query]->right->left = NULL;
			swap(nodes[query]->right, head);
			nodes[query]->right->left = nodes[query];
		}
	}

	node* cur = head;
	while (cur != NULL) {
		cout << cur->val + 1;
		if (cur->right) cout << " ";
		cur = cur->right;
	}
	cout << endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 6908
final_rank: 4

code_snippet: #include "bits/stdc++.h"

using namespace std;

using ll = long long;
using ld = long double;

const double PI = 3.1415926535897932384626433832795;
const ll MOD = 1000000007;

const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { -1, 0, 1, 0 };

int gcd(int x, int y) { return y ? gcd(y, x % y) : abs(x); }
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : abs(x); }
int lcm(int x, int y) { return x / gcd(x, y) * y; }
ll lcm(ll x, ll y) { return x / gcd(x, y) * y; }

struct node {
	int val;
	node *left, *right;
	node() : val(-1), left(NULL), right(NULL) { }
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n, q;
	cin >> n >> q;

	vector<int> a(n);
	for (auto &v : a) {
		cin >> v;
		v--;
	}

	vector<node*> nodes(n);
	for (int i = 0; i < n; i++) {
		nodes[i] = new node();
	}

	node *head = new node();
	node *tail = new node();

	for (int i = 0; i < n; i++) {
		if (i > 0) {
			nodes[a[i]]->left = nodes[a[i - 1]];
		} else {
			head = nodes[a[i]];
		}

		if (i + 1 < n) {
			nodes[a[i]]->right = nodes[a[i + 1]];
		} else {
			tail = nodes[a[i]];
		}

		nodes[a[i]]->val = a[i];
	}

	for (int i = 0; i < q; i++) {
		int query;
		cin >> query;
		query--;

		if (nodes[query] == head) {
			nodes[query]->left = tail;
			tail->right = nodes[query];

			nodes[query]->right->left = NULL;

			head = nodes[query]->right;
			nodes[query]->right = NULL;
			tail = nodes[query];
		} else if (nodes[query] == tail) {
			nodes[query]->right = head;
			head->left = nodes[query];

			nodes[query]->left->right = NULL;

			tail = nodes[query]->left;
			nodes[query]->left = NULL;
			head = nodes[query];
		} else {
			nodes[query]->left->right = NULL;
			swap(nodes[query]->left, tail);
			nodes[query]->left->right = nodes[query];
			nodes[query]->right->left = NULL;

			swap(nodes[query]->right, head);
			nodes[query]->right->left = nodes[query];
		}
	}

	node* cur = head;
	while (cur != NULL) {
		cout << cur->val + 1;
		if (cur->right) cout << " ";
		cur = cur->right;
	}
	cout << endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7040
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
//type
typedef long long ll;
#define pii pair<int, int>
#define vi vector<int>
//x * y * 1.0 can cause overflow
//constant
#define inf (int)(1e9+7)
#define mod (ll)(1e9+7)
#define eps 1e-10
//omission
#define eb emplace_back
#define F first
#define S second
#define SZ(x) ((int)(x).size())
#define all(v) v.begin(), v.end()
//manip
#define chmax(a, b) a = max(a, b)
#define chmin(a, b) a = min(a, b)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end(), v.end());
#define ceil(a, b) a / b + !!(a % b)
template<class T> T power(T a, T b)
{return b ? power(a * a % inf, b / 2) * (b % 2 ? a : 1) % inf : 1;}
#define LB(v, x) (int)(lower_bound(v.begin(), v.end(), x) - v.begin())
#define UB(v, x) (int)(upper_bound(v.begin(), v.end(), x) - v.begin())
//loop
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define rep3(i, st, n) for (int i = st; i < n; ++i)
//algorithm
//double pointer, l start, how many adds, can be 0 -> init r = l, sum = 0
//bfs, not x, y, i, j
//not !(i % 2), i % 2 == 0
//check sample again


bool zero(string a) {
    if (a[0] == '0' && SZ(a) >= 2) return 0;
    return 1;
}

int main() {
    //cast caution
    //look constraints always
    cin.tie(0); ios::sync_with_stdio(false);
    
    
    
    int N, Q; cin >> N >> Q;
    int a[N]; rep(i, N) {cin >> a[i]; a[i]--;}
    if (N == 1) {
        cout << a[0] + 1 << endl;
        return 0;
    }
    vector<pii> v(N);
    v[a[0]].F = -1;
    v[a[0]].S = a[1];
    v[a[N - 1]].S = -1;
    v[a[N - 1]].F = a[N - 2];
    rep3(i, 1, N - 1) {
        v[a[i]].F = a[i - 1];
        v[a[i]].S = a[i + 1];
    }
    
    //rep(i, N) cout << v[i].F << " " << v[i].S << endl;
    
    
    int lead = a[0], last = a[N - 1];
    
    rep(i, Q) {
        int q; cin >> q; q--;
        //a ... b c d ... e
        int a = lead; //af = v[a].F, as = v[a].S;
        int b = v[q].F; //bf = v[b].F, bs = v[b].S;
        int c = q; //cf = v[c].F, cs = v[c].S;
        int d = v[q].S; //df = v[d].F, ds = v[d].S;
        int e = last; //ef = v[e].F, es = v[e].S;
        
        //qが最後尾なら
        if (v[c].S == -1) {
            v[a].F = c;
            v[b].S = -1;
            v[c].S = a; v[c].F = -1;
            lead = c; last = b;
        } else if (v[c].F == -1) {
            v[c].F = e; v[c].S = -1;
            v[d].F = -1;
            v[e].S = c;
            lead = d; last = c;
        } else {
            v[a].F = c;
            v[b].S = -1;
            v[c].F = e; v[c].S = a;
            v[d].F = -1;
            v[e].S = c;
            lead = d; last = b;
        }
        
    }
    
    //rep(i, N) cout << v[i].F << " " << v[i].S << endl;
    
    //return 0;
    
    int now = lead;
    
    while (v[now].S != -1) {
        cout << now + 1 << " ";
        now = v[now].S;
        
    }
    cout << last + 1 << endl;
    
}

/*
 10^5個のqueryに答える
 毎回10^5個並び替えるわけにはいかない
 
 最小限何を変えたらいいか
 ある数で、手前と直後
 これは一部だけ変わる
 
 
 
 
 */
accuracy: 1
time_ms: 10
memory_kb: 4020
final_rank: 2

code_snippet: #include <cstdio>
#include <cstdint>
#include <cstddef>
#include <cassert>
#include <algorithm>
#include <utility>
#include <memory>
#include <array>
#include <iterator>
#include <vector>
#include <numeric>

template <typename Tp>
class avl_tree {
public:
  using value_type = Tp;
  using reference = value_type&;
  using const_reference = value_type const&;
  using difference_type = ptrdiff_t;
  using size_type = size_t;
  class iterator;
  class const_iterator;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

private:
  struct M_node {
    value_type value{};
    size_type height = 0;
    using link_type = std::shared_ptr<M_node>;
    link_type parent = nullptr;
    std::array<link_type, 2> children{{nullptr, nullptr}};
    size_type left_size = 0;

    M_node() = default;
    M_node(value_type const& value): value(value) {}
  };

  using link_type = typename M_node::link_type;
  using base_ptr = std::shared_ptr<M_node>;
  using const_base_ptr = std::shared_ptr<M_node const>;

  size_type M_size = 0;
  base_ptr M_root = nullptr;
  base_ptr M_begin = nullptr;
  base_ptr M_end = nullptr;

public:
  class iterator {
    friend avl_tree;
  public:
    using iterator_category = std::random_access_iterator_tag;
    using value_type = typename avl_tree::value_type;
    using difference_type = typename avl_tree::difference_type;
    using pointer = std::shared_ptr<typename avl_tree::value_type>;
    using reference = typename avl_tree::reference;

  private:
    using base_ptr = typename avl_tree::base_ptr;
    base_ptr node = nullptr;

    iterator(const_base_ptr const& ptr): node(std::const_pointer_cast<M_node>(ptr)) {}

  public:
    iterator() = default;
    iterator(iterator const&) = default;
    iterator(iterator&&) = default;
    iterator(base_ptr const& ptr): node(ptr) {}
    iterator& operator =(iterator const&) = default;
    iterator& operator =(iterator&&) = default;

    iterator& operator +=(difference_type count) { S_advance(node, count); return *this; }
    iterator& operator -=(difference_type count) { S_advance(node, -count); return *this; }
    iterator& operator ++() { S_increment(node); return *this; }
    iterator& operator --() { S_decrement(node); return *this; }
    iterator operator +(difference_type count) const { return iterator(*this) += count; }
    iterator operator -(difference_type count) const { return iterator(*this) -= count; }
    iterator operator ++(int) { iterator tmp = *this; ++*this; return tmp; }
    iterator operator --(int) { iterator tmp = *this; --*this; return tmp; }
    difference_type operator -(const_iterator const& other) const { return S_index(*this) - S_index(other); }

    reference operator *() { return node->value; }

    bool operator <(const_iterator const& other) const { return S_index(*this) < S_index(other); }
    bool operator ==(const_iterator const& other) const { return node == other.node; }
    bool operator <=(const_iterator const& other) const { return !(other < *this); }
    bool operator >(const_iterator const& other) const { return (other < *this); }
    bool operator >=(const_iterator const& other) const { return !(*this < other); }
    bool operator !=(const_iterator const& other) const { return !(*this == other); }
  };

  class const_iterator {
    friend avl_tree;
  public:
    using iterator_category = std::random_access_iterator_tag;
    using value_type = typename avl_tree::value_type;
    using difference_type = typename avl_tree::difference_type;
    using pointer = std::shared_ptr<typename avl_tree::value_type const>;
    using reference = typename avl_tree::const_reference;

  private:
    using base_ptr = typename avl_tree::const_base_ptr;
    using mutable_base_ptr = typename avl_tree::base_ptr;
    base_ptr node = nullptr;

  public:
    const_iterator() = default;
    const_iterator(const_iterator const&) = default;
    const_iterator(const_iterator&&) = default;
    const_iterator(iterator const& other): node(std::const_pointer_cast<M_node const>(other.node)) {}
    const_iterator(iterator&& other): node(std::const_pointer_cast<M_node const>(other.node)) {}
    const_iterator(base_ptr const& ptr): node(ptr) {}
    const_iterator(mutable_base_ptr const& ptr): node(std::const_pointer_cast<M_node const>(ptr)) {}
    
    const_iterator& operator =(const_iterator const&) = default;
    const_iterator& operator =(const_iterator&&) = default;

    const_iterator& operator +=(difference_type count) { S_advance(node, count); return *this; }
    const_iterator& operator -=(difference_type count) { S_advance(node, -count); return *this; }
    const_iterator& operator ++() { S_increment(node); return *this; }
    const_iterator& operator --() { S_decrement(node); return *this; }
    const_iterator operator +(difference_type count) const { return const_iterator(*this) += count; }
    const_iterator operator -(difference_type count) const { return const_iterator(*this) -= count; }
    const_iterator operator ++(int) { const_iterator tmp = *this; ++*this; return tmp; }
    const_iterator operator --(int) { const_iterator tmp = *this; --*this; return tmp; }
    difference_type operator -(const_iterator const& other) const { return S_index(*this) - S_index(other); }

    reference operator *() const { return node->value; }

    bool operator <(const_iterator const& other) const { return S_index(*this) < S_index(other); }
    bool operator ==(const_iterator const& other) const { return node == other.node; }
    bool operator <=(const_iterator const& other) const { return !(other < *this); }
    bool operator >(const_iterator const& other) const { return (other < *this); }
    bool operator >=(const_iterator const& other) const { return !(*this < other); }
    bool operator !=(const_iterator const& other) const { return !(*this == other); }
  };


private:
  static difference_type S_balance_factor(const_base_ptr node) {
    return S_balance_factor(std::const_pointer_cast<M_node>(node));
  }
  static difference_type S_balance_factor(base_ptr node) {
    std::array<difference_type, 2> height = {};
    for (size_t i = 0; i <= 1; ++i)
      if (node->children[i])
        height[i] = node->children[i]->height;

    return height[1] - height[0];
  }

  static void S_fix_height_one(base_ptr pos) {
    pos->height = 0;
    for (auto child: pos->children)
      if (child) pos->height = std::max(pos->height, child->height+1);
  }

  static void S_fix_height(base_ptr pos) {
    while (pos) {
      S_fix_height_one(pos);
      pos = pos->parent;
    }
  }

  static void S_fix_left_subtree_size(base_ptr pos, difference_type diff) {
    while (pos->parent) {
      if (pos == pos->parent->children[0])
        pos->parent->left_size += diff;
      pos = pos->parent;
    }
  }

  void M_prepare_sentinel() {
    assert(!M_root && !M_begin && !M_end);
    M_root = M_begin = M_end = base_ptr(new M_node);
  }

  static void S_clear_dfs(base_ptr root) {
    for (auto& child: root->children) {
      if (child) {
        S_clear_dfs(child);
        child = nullptr;
      }
    }
  }

  void M_clear() {
    M_size = 0;
    S_clear_dfs(M_root);
    M_begin = M_end = M_root = nullptr;
    M_prepare_sentinel();
  }

  static base_ptr S_leftmost(base_ptr pos) {
    while (pos->children[0]) pos = pos->children[0];
    return pos;
  }
  static base_ptr S_rightmost(base_ptr pos) {
    while (pos->children[1]) pos = pos->children[1];
    return pos;
  }

  static void S_increment(const_base_ptr& pos) { S_neighbor(pos, 1); }
  static void S_increment(base_ptr& pos) {
    const_base_ptr tmp = std::const_pointer_cast<M_node const>(pos);
    S_increment(tmp);
    pos = std::const_pointer_cast<M_node>(tmp);
  }
  static void S_decrement(const_base_ptr& pos) { S_neighbor(pos, 0); }
  static void S_decrement(base_ptr& pos) {
    const_base_ptr tmp = std::const_pointer_cast<M_node const>(pos);
    S_decrement(tmp);
    pos = std::const_pointer_cast<M_node>(tmp);
  }
  static void S_neighbor(const_base_ptr& pos, size_t dir) {
    if (pos->children[dir]) {
      pos = pos->children[dir];
      while (pos->children[!dir]) pos = pos->children[!dir];
      return;
    }
    while (true) {
      if (pos == pos->parent->children[!dir]) {
        pos = pos->parent;
        return;
      }
      pos = pos->parent;
    }
  }

  static void S_advance(const_base_ptr& pos, difference_type count = +1) {
    if (count > 0) {
      while (pos->parent) {
        difference_type tmp = count + S_index_diff_to_parent(pos);
        if (tmp < 0) break;
        count = tmp;
        pos = pos->parent;
      }
    } else /* if (count < 0) */ {
      while (pos->parent) {
        difference_type tmp = count + S_index_diff_to_parent(pos);
        if (tmp > 0) break;
        count = tmp;
        pos = pos->parent;
      }
    }

    while (count != 0) {
      if (count > 0) {
        pos = pos->children[1];
        count -= pos->left_size + 1;
      } else /* if (count < 0) */ {
        pos = pos->children[0];
        count += pos->parent->left_size - pos->left_size;
      }
    }
  }
  static void S_advance(base_ptr& pos, difference_type count = +1) {
    const_base_ptr tmp = std::const_pointer_cast<M_node const>(pos);
    S_advance(tmp, count);
    pos = std::const_pointer_cast<M_node>(tmp);
  }

  static size_type S_index(const_iterator pos) { return S_index(pos.node); }
  static size_type S_index(base_ptr pos) { return S_index(std::const_pointer_cast<M_node const>(pos)); }
  static size_type S_index(const_base_ptr pos) {
    size_type res = pos->left_size;
    while (pos->parent) {
      if (pos == pos->parent->children[1])
        res += pos->parent->left_size + 1;
      pos = pos->parent;
    }
    return res;
  }

  static difference_type S_index_diff_to_parent(base_ptr const& pos) {
    return S_index_diff_to_parent(std::const_pointer_cast<M_node const>(pos));
  }
  static difference_type S_index_diff_to_parent(const_base_ptr const& pos) {
    if (pos == pos->parent->children[0]) {
      return -static_cast<difference_type>(pos->parent->left_size - pos->left_size);
    } else {
      return pos->left_size + 1;
    }
  }

  static void S_rotate(base_ptr pos, size_t dir, base_ptr& root) {
    base_ptr child = pos->children[!dir];
    pos->children[!dir] = child->children[dir];
    if (child->children[dir])
      child->children[dir]->parent = pos;

    child->parent = pos->parent;
    if (!pos->parent) {
      root = child;
    } else if (pos == pos->parent->children[dir]) {
      pos->parent->children[dir] = child;
    } else {
      pos->parent->children[!dir] = child;
    }
    child->children[dir] = pos;
    pos->parent = child;

    if (dir == 0) {
      pos->parent->left_size += pos->left_size + 1;
    } else {
      pos->left_size -= pos->parent->left_size + 1;
    }
    // S_rotate() is intended to be called only by S_rebalance(),
    // which fix height more effectively
    // S_fix_height(pos);
  }
  void M_rotate(base_ptr pos, size_t dir) { S_rotate(pos, dir, M_root); }

  void M_rebalance(base_ptr pos) { S_rebalance(pos, M_root); }
  static void S_rebalance(base_ptr pos, base_ptr& root) {
    base_ptr start = pos;
    do {
      while (pos) {
        S_fix_height_one(pos);
        int bf = S_balance_factor(pos);
        if (!(-1 <= bf && bf <= +1)) break;
        pos = pos->parent;
      }
      if (!pos) return;

      size_t cdir = (S_balance_factor(pos) > 0);
      base_ptr child = pos->children[cdir];
      int bf = S_balance_factor(child);
      size_t gdir = ((cdir == 0)? (bf >= 0) : (bf > 0));
      base_ptr gchild = child->children[gdir];

      if (cdir == gdir) {
        S_rotate(pos, !cdir, root);
        S_fix_height_one(pos);
        pos = child;
      } else {
        S_rotate(child, cdir, root);
        S_rotate(pos, gdir, root);
        S_fix_height_one(child);
        S_fix_height_one(pos);
        pos = gchild;
      }
    } while (true);
  }

  void M_node_swap(base_ptr lhs, base_ptr rhs) {
    // swaps the position of two nodes, but corresponding iterators remain valid
    S_node_swap(lhs, rhs, M_begin, M_end, M_root);
  }
  static void S_node_swap(base_ptr lhs, base_ptr rhs, base_ptr& begin, base_ptr& end, base_ptr& root) {
    if (root == lhs) {
      root = rhs;
    } else if (root == rhs) {
      root = lhs;
    }
    if (begin == lhs) {
      begin = rhs;
    } else if (begin == rhs) {
      begin = lhs;
    }
    if (end == lhs) {
      end = rhs;
    } else if (end == rhs) {
      end = lhs;
    }

    base_ptr lpar = lhs->parent;
    base_ptr rpar = rhs->parent;
    for (auto child: lhs->children)
      if (child) child->parent = rhs;
    for (auto child: rhs->children)
      if (child) child->parent = lhs;

    if (lpar) {
      size_type ldir = (lhs == lpar->children[1]);
      lpar->children[ldir] = rhs;
    }
    if (rpar) {
      size_type rdir = (rhs == rpar->children[1]);
      rpar->children[rdir] = lhs;
    }

    std::swap(lhs->children, rhs->children);
    std::swap(lhs->parent, rhs->parent);
    std::swap(lhs->left_size, rhs->left_size);
    std::swap(lhs->height, rhs->height);
  }

  base_ptr M_insert(const_base_ptr pos, base_ptr newnode) {
    return M_insert(std::const_pointer_cast<M_node>(pos), newnode);
  }
  base_ptr M_insert(base_ptr pos, base_ptr newnode) {
    ++M_size;
    return S_insert(pos, newnode, M_begin, M_root);
  }
  static base_ptr S_insert(base_ptr pos, base_ptr newnode, base_ptr& begin, base_ptr& root) {
    if (pos->children[0]) {
      S_decrement(pos);
      pos->children[1] = newnode;
    } else {
      pos->children[0] = newnode;
      if (pos == begin) begin = newnode;
    }
    newnode->parent = pos;
    S_fix_height(pos);
    S_fix_left_subtree_size(newnode, +1);
    S_rebalance(newnode, root);
    return newnode;
  }
  
  static base_ptr S_push_back(base_ptr newnode, base_ptr& root) {
    if (!root) return (root = newnode);

    base_ptr pos = S_rightmost(root);
    pos->children[1] = newnode;
    newnode->parent = pos;
    newnode->left_size = 0;
    S_fix_height(pos);
    S_fix_left_subtree_size(newnode, +1);
    S_rebalance(newnode, root);
    return newnode;
  }

  base_ptr M_erase(const_base_ptr pos) { return M_erase(std::const_pointer_cast<M_node>(pos)); }
  base_ptr M_erase(base_ptr pos) {
    base_ptr next = S_erase(pos, M_begin, M_end, M_root);
    --M_size;
    return next;
  }
  static base_ptr S_erase(base_ptr pos, base_ptr& begin, base_ptr& end, base_ptr& root) {
    if (pos->children[0] && pos->children[1]) {
      base_ptr tmp = pos;
      S_advance(tmp);
      S_node_swap(pos, tmp, begin, end, root);
    }

    base_ptr next = pos;
    if (next != end) S_increment(next);
    if (pos == begin) begin = next;

    base_ptr child = pos->children[0];
    if (!child) child = pos->children[1];

    if (child) {
      child->parent = pos->parent;
    } else if (pos == end) {
      next = end = pos->parent;
    }

    if (!pos->parent) {
      root = child;
    } else {
      S_fix_left_subtree_size(pos, -1);
      size_type dir = (pos == pos->parent->children[1]);
      pos->parent->children[dir] = child;
      S_fix_height(pos->parent);
      S_rebalance(pos->parent, root);
    }
    return next;
  }

  static void S_check(base_ptr pos) {
    if (!pos) {
      fprintf(stderr, "(nil)\n");
    } else {
      size_t h[2] = {};
      for (size_t i = 0; i <= 1; ++i)
        if (pos->children[i]) h[i] = pos->children[i]->height;
      fprintf(stderr, "node at %p, height[%zu, %zu], value{%d}\n",
              pos.get(), h[0], h[1], pos->value);
    }
  }

  static void S_inspect_dfs(const const_base_ptr& root, size_type depth = 0) {
    if (!root) {
      fprintf(stderr, "(nil)\n");
      return;
    }
    auto child = root->children[1];
    if (child) S_inspect_dfs(child, depth+1);
    fprintf(stderr, "%*s-(%p) (%zu): %d (H: %zu) (P: %p) (C: %p, %p)\n",
            static_cast<int>(depth), "",
            root.get(),
            root->left_size,
            root->value,
            root->height,
            root->parent.get(),
            root->children[0].get(),
            root->children[1].get()
            );
    child = root->children[0];
    if (child) S_inspect_dfs(child, depth+1);
  }

  base_ptr M_merge(avl_tree&& other) { return M_merge(std::move(other)); }
  base_ptr M_merge(avl_tree& other) {
    if (other.empty()) return M_end;
    if (empty()) {
      *this = std::move(other);
      return M_begin;
    }
    M_end->value = 123;
    other.M_end->value = 456;
    size_type left_size = M_size + 1;  // +1 for M_end
    M_size += other.M_size + 2;  // +1 for dummy, +1 for M_end
    base_ptr med(new M_node);
    M_root = S_merge(M_root, other.M_root, med, left_size);

    base_ptr end = M_end;
    M_end = other.M_end;

    base_ptr tmp(new M_node);
    M_node_swap(other.M_end, tmp);
    other.M_size = 0;
    other.M_root = other.M_begin = other.M_end;

    M_node_swap(end, tmp);
    M_end = end;
    M_erase(tmp);
    med = M_erase(med);

    return med;
  }

  static base_ptr S_merge(base_ptr left, base_ptr right, base_ptr med, size_type left_size) {
    med->left_size = left_size;
    med->height = 0;
    if (!left && !right) return med;
    if (!left) {
      base_ptr begin = S_leftmost(right);
      S_insert(begin, med, begin, right);
      return right;
    }
    if (!right) {
      S_push_back(med, left);
      return left;
    }
    base_ptr left_root = left;
    base_ptr right_root = right;
    base_ptr root = med;
    if (left->height < right->height) {
      size_t h = left->height + 1;
      while (right->children[0] && right->height > h)
        right = right->children[0];  // left spine
      if (right->parent) {
        med->parent = right->parent;
        right->parent->children[0] = med;
        root = right_root;
      }
    } else if (left->height > right->height) {
      size_t h = right->height + 1;
      while (left->children[1] && left->height > h) {
        med->left_size -= left->left_size + 1;
        left = left->children[1];  // right spine
      }
      if (left->parent) {
        med->parent = left->parent;
        left->parent->children[1] = med;
        root = left_root;
      }
    }

    left->parent = right->parent = med;
    med->children[0] = left;
    med->children[1] = right;
    S_fix_left_subtree_size(med, med->left_size+1);
    S_fix_height(med);
    S_rebalance(med, root);

    return root;
  }

  avl_tree M_split(base_ptr pos) {
    if (pos == M_end) return avl_tree();

    size_t left_size = S_index(pos) - S_index(M_begin);
    size_t right_size = M_size - left_size;

    avl_tree right;
    std::tie(M_root, right.M_root) = S_split(pos);

    right.M_begin = S_leftmost(right.M_root);
    right.M_end = S_rightmost(right.M_root);
    base_ptr end(new M_node);
    base_ptr tmp(right.M_end);
    S_node_swap(end, tmp, right.M_begin, right.M_end, right.M_root);
    S_push_back(tmp, M_root);
    M_end = tmp;

    right.M_size = right_size;
    M_size = left_size;
    return right;
  }

  static std::pair<base_ptr, base_ptr> S_split(base_ptr pos) {
    // XXX pos should not point the last element
    base_ptr left_root = pos->children[0];
    base_ptr right_root = pos->children[1];
    size_type acc_size = pos->left_size;
    if (left_root) left_root->parent = nullptr;
    if (right_root) right_root->parent = nullptr;
    base_ptr crit = pos;

    base_ptr parent = pos->parent;
    while (parent) {
      size_type dir = (pos == parent->children[1]);
      pos = parent;
      parent = parent->parent;
      pos->parent = nullptr;
      size_type size;
      if (dir == 1) {
        // merge leftward
        size = pos->left_size;
        base_ptr subroot = pos->children[0];
        pos->children[0] = pos->children[1] = nullptr;
        if (subroot) subroot->parent = nullptr;
        left_root = S_merge(subroot, left_root, pos, size);
        left_root->parent = nullptr;
        acc_size += size + 1;
      } else {
        // merge rightward
        size = pos->left_size - acc_size - 1;
        base_ptr subroot = pos->children[1];
        pos->children[0] = pos->children[1] = nullptr;
        if (subroot) subroot->parent = nullptr;
        right_root = S_merge(right_root, subroot, pos, size);
        right_root->parent = nullptr;
      }
    }

    crit->children[0] = crit->children[1] = nullptr;
    crit->left_size = 0;
    {
      base_ptr begin = S_leftmost(right_root);
      S_insert(S_leftmost(right_root), crit, begin, right_root);
    }
    return {left_root, right_root};
  }

  static void S_deep_copy_dfs(base_ptr& dst, base_ptr const& src) {
    dst = base_ptr(new M_node(src->value));
    dst->parent = src->parent;
    dst->left_size = src->left_size;
    dst->height = src->height;
    for (size_t i = 0; i <= 1; ++i) {
      if (src->children[i])
        S_deep_copy_dfs(dst->children[i], src->children[i]);
    }
  }

  void M_deep_copy(avl_tree const& other) {
    fprintf(stderr, "deep-copied\n");
    M_size = other.M_size;
    S_deep_copy_dfs(M_root, other.M_root);
    M_begin = S_leftmost(M_root);
    M_end = S_rightmost(M_root);
  }

public:
  avl_tree() { M_prepare_sentinel(); }
  avl_tree(avl_tree const& other) { M_deep_copy(other); }
  avl_tree(avl_tree&&) = default;
  avl_tree(size_type count, value_type const& value = value_type{}): avl_tree() {
    while (count--) push_back(value);
  }
  template <typename InputIt, typename = std::_RequireInputIter<InputIt>>
  avl_tree(InputIt first, InputIt last): avl_tree() {
    while (first != last) push_back(*first++);
  }
  avl_tree(std::initializer_list<value_type> ilist): avl_tree(ilist.begin(), ilist.end()) {}

  avl_tree& operator =(avl_tree const& other) { M_deep_copy(other); }
  avl_tree& operator =(avl_tree&&) = default;

  // # element access
  // ## at
  reference at(size_t i) {
    if (i >= size()) throw std::out_of_range("i >= size()");
    return *(begin() + i);
  }
  const_reference at(size_t i) const {
    if (i >= size()) throw std::out_of_range("i >= size()");
    return (*cbegin() + i);
  }
  // ## operator []
  reference operator [](size_t i) { return *(begin() + i); }
  const_reference operator [](size_t i) const { return *(cbegin() + i); }
  // ## front and back
  reference first() { return *begin(); }
  const_reference first() const { return *cbegin(); }
  reference back() { return *rbegin(); }
  const_reference back() const { return *crbegin(); }

  // # iterators
  // ## begin
  iterator begin() { return M_begin; }
  const_iterator begin() const { return M_begin; }
  const_iterator cbegin() const { return M_begin; }
  // ## end
  iterator end() { return M_end; }
  const_iterator end() const { return M_end; }
  const_iterator cend() const { return M_end; }
  // ## rbegin
  reverse_iterator rbegin() { return reverse_iterator(M_end); }
  const_reverse_iterator rbegin() const { return const_reverse_iterator(M_end); }
  const_reverse_iterator crbegin() const { return const_reverse_iterator(M_end); }
  // ## rend
  reverse_iterator rend() { return reverse_iterator(M_begin); }
  const_reverse_iterator rend() const { return const_reverse_iterator(M_begin); }
  const_reverse_iterator crend() const { return const_reverse_iterator(M_begin); }
  // ## lower_bound
  template <typename Comparator>
  iterator lower_bound(value_type const& value, Comparator comp) {
    base_ptr pos = M_root;
    base_ptr res = pos;
    while (pos) {
      size_t dir = (pos != M_end) && comp(pos->value, value);
      if (dir == 0) res = pos;
      pos = pos->children[dir];
    }
    return res;
  }
  iterator lower_bound(value_type const& value) { return lower_bound(value, std::less<value_type>()); }
  // ## upper_bound
  template <typename Comparator>
  iterator upper_bound(value_type const& value, Comparator comp) {
    base_ptr pos = M_root;
    base_ptr res = pos;
    while (pos) {
      size_t dir = (pos != M_end) && !comp(value, pos->value);
      if (dir == 0) res = pos;
      pos = pos->children[dir];
    }
    return res;
  }
  iterator upper_bound(value_type const& value) { return upper_bound(value, std::less<value_type>()); }

  // # capacity
  // ## empty
  bool empty() const { return M_size == 0; }
  // ## size
  size_type size() const { return M_size; }

  // # modifiers
  // ## clear
  void clear() { M_clear(); }
  // ## insert and emplace
  iterator insert(const_iterator pos, value_type const& value) {
    return M_insert(pos.node, base_ptr(new M_node(value)));
  }
  iterator insert(const_iterator pos, value_type&& value) {
    return M_insert(pos.node, base_ptr(new M_node(std::move(value))));
  }
  iterator insert(const_iterator pos, size_t count, value_type const& value) {
    iterator res = pos;
    while (count--) res = M_insert(pos.node, base_ptr(new M_node(value)));
    return res;
  }
  template <typename InputIt>
  iterator insert(const_iterator pos, InputIt first, InputIt last) {
    iterator res = pos;
    while (first != last) res = M_insert(pos.node, base_ptr(new M_node(*first++)));
    return res;
  }
  iterator insert(const_iterator pos, std::initializer_list<value_type> ilist) {
    return insert(pos, ilist.begin(), ilist.end());
  }
  template <typename... Args>
  iterator emplace(const_iterator pos, Args&&... args) {
    return M_insert(pos.node, base_ptr(new M_node(std::forward<Args>(args)...)));
  }
  // ## erase
  iterator erase(iterator pos) { return M_erase(pos.node); }
  iterator erase(const_iterator pos) { return M_erase(pos.node); }
  iterator erase(const_iterator first, const_iterator last) {
    while (first != last) first = erase(first);
    return first;
  }
  // ## push_back and push_front
  void push_back(value_type const& value) { insert(cend(), value); }
  void push_back(value_type&& value) { insert(cend(), std::move(value)); }
  void push_front(value_type const& value) { insert(cbegin(), value); }
  void push_front(value_type&& value) { insert(cbegin(), std::move(value)); }
  template <typename... Args>
  void emplace_back(Args&&... args) {
    M_insert(M_end, const_base_ptr(new M_node(std::forward<Args>(args)...)));
  }
  template <typename... Args>
  void emplace_front(Args&&... args) {
    M_insert(M_begin, const_base_ptr(new M_node(std::forward<Args>(args)...)));
  }
  // ## pop_back and pop_front
  void pop_back() { erase(--end()); }
  void pop_front() { erase(begin()); }
  // ## merge and split
  iterator merge(avl_tree& other) { return M_merge(other); }
  iterator merge(avl_tree&& other) { return M_merge(std::move(other)); }
  avl_tree split(const_iterator pos) {
    return  M_split(std::const_pointer_cast<M_node>(pos.node));
  }

  // # debug
  // ## inspect
  void inspect() const {
    fprintf(stderr, "root: %p\n", M_root.get());
    fprintf(stderr, "begin: %p\n", M_begin.get());
    fprintf(stderr, "end: %p\n", M_end.get());
    fprintf(stderr, "size: %zu\n", M_size);
    S_inspect_dfs(std::const_pointer_cast<M_node const>(M_root));
    fprintf(stderr, "===\n");
  }

  void verify() const {
    fprintf(stderr, "begin: %p\n", M_begin.get());
    fprintf(stderr, "end: %p\n", M_end.get());
    bool violated = false;
    for (auto it = begin(); it != end(); ++it) {
      const_base_ptr node = it.node;
      // fprintf(stderr, "%p\n", node.get());
      // fprintf(stderr, "%d\n", node->value);
      int bf = S_balance_factor(node);
      if (!(-1 <= bf && bf <= +1)) {
        fprintf(stderr, "balance factor of %p (%d): %d\n",
                node.get(), node->value, bf);
        // assert(-1 <= bf && bf <= +1);
        violated = true;
      }
    }
    if (violated) inspect();
  }
};

int main() {
  size_t N, Q;
  scanf("%zu %zu", &N, &Q);

  avl_tree<int> r(N);
  for (auto it = r.begin(); it != r.end(); ++it) {
    int ri;
    scanf("%d", &ri);
    --ri;
    *it = ri;
  }

  std::vector<typename avl_tree<int>::iterator> its(N+1);
  for (auto it = r.begin(); it != r.end(); ++it) {
    its[*it] = it;
  }

  for (size_t i = 0; i < Q; ++i) {
    size_t q;
    scanf("%zu", &q);
    --q;
    auto m = r.split(its[q]);
    auto l = m.split(m.begin()+1);

    l.merge(m);
    l.merge(r);
    r = std::move(l);
  }

  std::vector<int> res;
  for (auto ri: r)
    if (ri != int(N)) res.push_back(ri);
  for (size_t i = 0; i < N; ++i)
    printf("%d%c", res[i]+1, i+1<N? ' ':'\n');
}
accuracy: 1
time_ms: 810
memory_kb: 15460
final_rank: 17