Problem p03198 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#define rg register
#define ll long long
#define LDB long double
#define ull unsigned long long
#define view(i, x) for (rg int i = hd[x]; i != -1; i = e[i].nt)
#define go(i, x, a) for (rg int i = a; i < x; i++)
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
using namespace std;

const int maxn = 2 * 1e5 + 5;
ll n, dp[2][maxn], la[maxn];
ll q[maxn], tl;
ll p4[20], a[maxn];

inline ll rd() {
  ll ret = 0, af = 1;
  char gc = getchar();
  while (gc < '0' || gc > '9') {
    if (gc == '-')
      af = -af;
    gc = getchar();
  }
  while (gc >= '0' && gc <= '9')
    ret = ret * 10 + gc - '0', gc = getchar();
  return ret * af;
}

inline int find(ll x, ll y) {
  if (x == y)
    return -1;
  int l = 0, r = 15;
  while (l < r) {
    int mid = (l + r + 1) / 2;
    if ((ull)p4[mid] * x < y)
      l = mid;
    else
      r = mid - 1;
  }
  return l;
}

inline int get(ll x, ll y) {
  int l = 0, r = 15;
  while (l < r) {
    int mid = (l + r + 1) / 2;
    if ((ull)p4[mid] * x <= y)
      l = mid;
    else
      r = mid - 1;
  }
  return l;
}

int main() {
  freopen("data.in", "r", stdin);
  freopen("me.out", "w", stdout);
  p4[0] = 1;
  go(i, 16, 1) p4[i] = 4 * p4[i - 1];
  n = rd();
  go(i, n + 1, 1) a[i] = rd();
  dp[1][n] = 0;
  la[n] = 0;
  for (rg int i = n - 1; i >= 1; i--) {
    dp[1][i] = dp[1][i + 1];
    if (a[i] <= a[i + 1])
      la[i] = get(a[i], a[i + 1]), q[++tl] = i;
    else {
      int qs = find(a[i + 1], a[i]) + 1;
      while (qs > 0) {
        if (tl == 0)
          break;
        int pos = q[tl], tt = 0;
        if (la[pos] > qs)
          tt = qs, la[pos] -= qs, qs = 0;
        else
          tt = la[pos], qs -= la[pos], la[pos] = 0, tl--;
        dp[1][i] += (ll)tt * (ll)(pos - i);
      }
      dp[1][i] += qs * (ll)(n - i);
    }
  }
  tl = 0;
  memset(la, 0, sizeof(la));
  dp[0][1] = 0;
  la[1] = 0;
  go(i, n + 1, 1) a[i] *= 2;
  for (rg int i = 2; i <= n; i++) {
    dp[0][i] = dp[0][i - 1];
    if (a[i] < a[i - 1])
      la[i] = get(a[i], a[i - 1]), q[++tl] = i;
    else {
      int qs = find(a[i - 1], a[i]) + 1;
      while (qs > 0) {
        if (tl == 0)
          break;
        int pos = q[tl], tt = 0;
        if (la[pos] > qs)
          tt = qs, la[pos] -= qs, qs = 0;
        else
          tt = la[pos], qs -= la[pos], la[pos] = 0, tl--;
        dp[0][i] += (ll)tt * (ll)(i - pos);
      }
      dp[0][i] += qs * (ll)(i - 1);
    }
  }
  for (rg int i = n; i >= 1; i--)
    dp[0][i] = dp[0][i - 1];
  go(i, n + 1, 1) dp[0][i] *= 2, dp[1][i] *= 2;
  go(i, n + 1, 1) dp[0][i] += i - 1;
  ll ans = 1e18;
  int pos = 0;
  go(i, n + 1, 1) if (dp[1][i] + dp[0][i] < ans) ans = dp[1][i] + dp[0][i];
  printf("%lld", ans);
  return 0;
} // Faze


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#define rg register
#define ll long long
#define LDB long double
#define ull unsigned long long
#define view(i, x) for (rg int i = hd[x]; i != -1; i = e[i].nt)
#define go(i, x, a) for (rg int i = a; i < x; i++)
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
using namespace std;

const int maxn = 2 * 1e5 + 5;
ll n, dp[2][maxn], la[maxn];
ll q[maxn], tl;
ll p4[20], a[maxn];

inline ll rd() {
  ll ret = 0, af = 1;
  char gc = getchar();
  while (gc < '0' || gc > '9') {
    if (gc == '-')
      af = -af;
    gc = getchar();
  }
  while (gc >= '0' && gc <= '9')
    ret = ret * 10 + gc - '0', gc = getchar();
  return ret * af;
}

inline int find(ll x, ll y) {
  if (x == y)
    return -1;
  int l = 0, r = 15;
  while (l < r) {
    int mid = (l + r + 1) / 2;
    if ((ull)p4[mid] * x < y)
      l = mid;
    else
      r = mid - 1;
  }
  return l;
}

inline int get(ll x, ll y) {
  int l = 0, r = 15;
  while (l < r) {
    int mid = (l + r + 1) / 2;
    if ((ull)p4[mid] * x <= y)
      l = mid;
    else
      r = mid - 1;
  }
  return l;
}

int main() {
  p4[0] = 1;
  go(i, 16, 1) p4[i] = 4 * p4[i - 1];
  n = rd();
  go(i, n + 1, 1) a[i] = rd();
  dp[1][n] = 0;
  la[n] = 0;
  for (rg int i = n - 1; i >= 1; i--) {
    dp[1][i] = dp[1][i + 1];
    if (a[i] <= a[i + 1])
      la[i] = get(a[i], a[i + 1]), q[++tl] = i;
    else {
      int qs = find(a[i + 1], a[i]) + 1;
      while (qs > 0) {
        if (tl == 0)
          break;
        int pos = q[tl], tt = 0;
        if (la[pos] > qs)
          tt = qs, la[pos] -= qs, qs = 0;
        else
          tt = la[pos], qs -= la[pos], la[pos] = 0, tl--;
        dp[1][i] += (ll)tt * (ll)(pos - i);
      }
      dp[1][i] += qs * (ll)(n - i);
    }
  }
  tl = 0;
  memset(la, 0, sizeof(la));
  dp[0][1] = 0;
  la[1] = 0;
  go(i, n + 1, 1) a[i] *= 2;
  for (rg int i = 2; i <= n; i++) {
    dp[0][i] = dp[0][i - 1];
    if (a[i] < a[i - 1])
      la[i] = get(a[i], a[i - 1]), q[++tl] = i;
    else {
      int qs = find(a[i - 1], a[i]) + 1;
      while (qs > 0) {
        if (tl == 0)
          break;
        int pos = q[tl], tt = 0;
        if (la[pos] > qs)
          tt = qs, la[pos] -= qs, qs = 0;
        else
          tt = la[pos], qs -= la[pos], la[pos] = 0, tl--;
        dp[0][i] += (ll)tt * (ll)(i - pos);
      }
      dp[0][i] += qs * (ll)(i - 1);
    }
  }
  for (rg int i = n; i >= 1; i--)
    dp[0][i] = dp[0][i - 1];
  go(i, n + 1, 1) dp[0][i] *= 2, dp[1][i] *= 2;
  go(i, n + 1, 1) dp[0][i] += i - 1;
  ll ans = 1e18;
  int pos = 0;
  go(i, n + 1, 1) if (dp[1][i] + dp[0][i] < ans) ans = dp[1][i] + dp[0][i];
  printf("%lld", ans);
  return 0;
} // Faze