Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int mn[maxn << 2][2];
int a[maxn];
bool lazy[maxn << 2];
int num[maxn << 2];
void Push_down(int id) {
  lazy[id << 1] ^= 1;
  lazy[id << 1 | 1] ^= 1;
  lazy[id] = 0;
  swap(mn[id << 1][0], mn[id << 1][1]);
  swap(mn[id << 1 | 1][0], mn[id << 1 | 1][1]);
}
void Push_up(int id) {
  int x = mn[id << 1][0], y = mn[id << 1 | 1][0];
  if (a[x] > a[y])
    mn[id][0] = y;
  else
    mn[id][0] = x;
  x = mn[id << 1][1];
  y = mn[id << 1 | 1][1];
  if (a[x] > a[y])
    mn[id][1] = y;
  else
    mn[id][1] = x;
}
void init(int id, int l, int r) {
  if (l == r) {
    scanf("%d", a + l);
    mn[id][(l & 1)] = l;
    mn[id][(l & 1) ^ 1] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  init(id << 1, l, mid);
  init(id << 1 | 1, mid + 1, r);
  Push_up(id);
}

int Find(int id, int l, int r, int tl, int tr, int jiou) {
  if (l == tl && r == tr) {
    // printf("%d %d %d %d %d find\n",id,l,r,jiou,mn[id][jiou]);
    return mn[id][jiou];
  }
  if (lazy[id])
    Push_down(id);
  int mid = (l + r) >> 1;
  if (tr <= mid)
    return Find(id << 1, l, mid, tl, tr, jiou);
  if (tl > mid)
    return Find(id << 1 | 1, mid + 1, r, tl, tr, jiou);
  int x = Find(id << 1, l, mid, tl, mid, jiou),
      y = Find(id << 1 | 1, mid + 1, r, mid + 1, tr, jiou);
  if (a[x] > a[y])
    return y;
  return x;
}
int get(int id, int l, int r, int v) {
  if (r <= v)
    return num[id];
  int mid = (l + r) >> 1;
  if (v > mid)
    return get(id << 1, l, mid, v) + get(id << 1 | 1, mid + 1, r, v);
  return get(id << 1, l, mid, v);
}
int getr(int id, int l, int r, int v) {
  if (l == r)
    return l;
  int mid = (l + r) >> 1;
  if (num[id << 1] <= v)
    return getr(id << 1 | 1, mid + 1, r, v - num[id << 1]);
  else
    return getr(id << 1, l, mid, v);
}
void up(int id, int l, int r, int v) {
  num[id]++;
  if (l == r)
    return;
  int mid = (l + r) >> 1;
  if (v <= mid)
    up(id << 1, l, mid, v);
  else
    up(id << 1 | 1, mid + 1, r, v);
}
void Up(int id, int l, int r, int v) {
  if (l == r) {
    mn[id][0] = mn[id][1] = 0;
    return;
  }
  if (lazy[id])
    Push_down(id);
  int mid = (l + r) >> 1;
  if (v <= mid)
    Up(id << 1, l, mid, v);
  else
    Up(id << 1 | 1, mid + 1, r, v);
  Push_up(id);
}
void upda(int id, int l, int r, int tl, int tr) {
  // printf("%d %d %d %d %d  upda\n",id,l,r,tl,tr);
  if (l == tl && r == tr) {
    lazy[id] ^= 1;
    swap(mn[id][0], mn[id][1]);
    // printf("%d %d %d %d %dmn\n",id,l,r,mn[id][0],mn[id][1]);
    return;
  }
  if (lazy[id])
    Push_down(id);
  int mid = (l + r) >> 1;
  if (tr <= mid)
    upda(id << 1, l, mid, tl, tr);
  else if (tl > mid)
    upda(id << 1 | 1, mid + 1, r, tl, tr);
  else {
    upda(id << 1, l, mid, tl, mid);
    upda(id << 1 | 1, mid + 1, r, mid + 1, tr);
  }
  Push_up(id);
}
void check(int id, int l, int r) {
  if (l == r) {
    printf("%d ", num[id]);
    return;
  }
  int mid = (l + r) >> 1;
  check(id << 1, l, mid);
  check(id << 1 | 1, mid + 1, r);
}
int main() {
  int n;
  scanf("%d", &n);
  a[0] = 1e9;
  init(1, 1, n);
  for (int i = 1; i <= n / 2; i++) {
    int t1 = Find(1, 1, n, 1, n, 1);
    int tnum = get(1, 1, n, t1);
    int r = getr(1, 1, n, tnum);
    int t2 = Find(1, 1, n, t1, r, 0);
    printf("%d %d ", a[t1], a[t2]);
    // check(1,1,n);printf("check  \n");
    // printf("%d %d %d %d %d  %drr\n",a[t1],a[t2],t1,t2,tnum,r);
    up(1, 1, n, t1);
    up(1, 1, n, t2);
    Up(1, 1, n, t1);
    Up(1, 1, n, t2);
    if (t1 + 1 < t2)
      upda(1, 1, n, t1 + 1, t2 - 1);
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int mn[maxn << 2][2];
int a[maxn];
bool lazy[maxn << 2];
int num[maxn << 2];
void Push_down(int id) {
  lazy[id << 1] ^= 1;
  lazy[id << 1 | 1] ^= 1;
  lazy[id] = 0;
  swap(mn[id << 1][0], mn[id << 1][1]);
  swap(mn[id << 1 | 1][0], mn[id << 1 | 1][1]);
}
void Push_up(int id) {
  int x = mn[id << 1][0], y = mn[id << 1 | 1][0];
  if (a[x] > a[y])
    mn[id][0] = y;
  else
    mn[id][0] = x;
  x = mn[id << 1][1];
  y = mn[id << 1 | 1][1];
  if (a[x] > a[y])
    mn[id][1] = y;
  else
    mn[id][1] = x;
}
void init(int id, int l, int r) {
  if (l == r) {
    scanf("%d", a + l);
    mn[id][(l & 1)] = l;
    mn[id][(l & 1) ^ 1] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  init(id << 1, l, mid);
  init(id << 1 | 1, mid + 1, r);
  Push_up(id);
}

int Find(int id, int l, int r, int tl, int tr, int jiou) {
  if (l == tl && r == tr) {
    // printf("%d %d %d %d %d find\n",id,l,r,jiou,mn[id][jiou]);
    return mn[id][jiou];
  }
  if (lazy[id])
    Push_down(id);
  int mid = (l + r) >> 1;
  if (tr <= mid)
    return Find(id << 1, l, mid, tl, tr, jiou);
  if (tl > mid)
    return Find(id << 1 | 1, mid + 1, r, tl, tr, jiou);
  int x = Find(id << 1, l, mid, tl, mid, jiou),
      y = Find(id << 1 | 1, mid + 1, r, mid + 1, tr, jiou);
  if (a[x] > a[y])
    return y;
  return x;
}
int get(int id, int l, int r, int v) {
  if (r <= v)
    return num[id];
  int mid = (l + r) >> 1;
  if (v > mid)
    return get(id << 1, l, mid, v) + get(id << 1 | 1, mid + 1, r, v);
  return get(id << 1, l, mid, v);
}
int getr(int id, int l, int r, int v) {
  if (l == r)
    return l;
  int mid = (l + r) >> 1;
  if (num[id << 1] <= v)
    return getr(id << 1 | 1, mid + 1, r, v - num[id << 1]);
  else
    return getr(id << 1, l, mid, v);
}
void up(int id, int l, int r, int v) {
  num[id]++;
  if (l == r)
    return;
  int mid = (l + r) >> 1;
  if (v <= mid)
    up(id << 1, l, mid, v);
  else
    up(id << 1 | 1, mid + 1, r, v);
}
void Up(int id, int l, int r, int v) {
  if (l == r) {
    mn[id][0] = mn[id][1] = 0;
    return;
  }
  if (lazy[id])
    Push_down(id);
  int mid = (l + r) >> 1;
  if (v <= mid)
    Up(id << 1, l, mid, v);
  else
    Up(id << 1 | 1, mid + 1, r, v);
  Push_up(id);
}
void upda(int id, int l, int r, int tl, int tr) {
  // printf("%d %d %d %d %d  upda\n",id,l,r,tl,tr);
  if (l == tl && r == tr) {
    lazy[id] ^= 1;
    swap(mn[id][0], mn[id][1]);
    // printf("%d %d %d %d %dmn\n",id,l,r,mn[id][0],mn[id][1]);
    return;
  }
  if (lazy[id])
    Push_down(id);
  int mid = (l + r) >> 1;
  if (tr <= mid)
    upda(id << 1, l, mid, tl, tr);
  else if (tl > mid)
    upda(id << 1 | 1, mid + 1, r, tl, tr);
  else {
    upda(id << 1, l, mid, tl, mid);
    upda(id << 1 | 1, mid + 1, r, mid + 1, tr);
  }
  Push_up(id);
}
void check(int id, int l, int r) {
  if (l == r) {
    printf("%d ", num[id]);
    return;
  }
  int mid = (l + r) >> 1;
  check(id << 1, l, mid);
  check(id << 1 | 1, mid + 1, r);
}
int main() {
  int n;
  scanf("%d", &n);
  a[0] = 1e9;
  init(1, 1, n);
  for (int i = 1; i <= n / 2; i++) {
    int t1 = Find(1, 1, n, 1, n, 1);
    int tnum = get(1, 1, n, t1);
    int r = getr(1, 1, n, tnum);
    int t2 = Find(1, 1, n, t1, r, 0);
    printf("%d %d ", a[t1], a[t2]);
    // check(1,1,n);printf("check  \n");
    // printf("%d %d %d %d %d  %drr\n",a[t1],a[t2],t1,t2,tnum,r);
    up(1, 1, n, t1);
    up(1, 1, n, t2);
    Up(1, 1, n, t1);
    Up(1, 1, n, t2);
    if (t1 + 1 < t2)
      upda(1, 1, n, t1 + 1, t2 - 1);
  }
  return 0;
}