Problem p03198 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
clock_t t = clock();
namespace my_std {
using namespace std;
#define pii pair<int, int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i, x, y) for (int i = (x); i <= (y); i++)
#define drep(i, x, y) for (int i = (x); i >= (y); i--)
#define go(x) for (int i = head[x]; i; i = edge[i].nxt)
#define templ template <typename T>
#define sz 101010
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l, T r) { return uniform_int_distribution<T>(l, r)(rng); }
templ inline bool chkmax(T &x, T y) { return x < y ? x = y, 1 : 0; }
templ inline bool chkmin(T &x, T y) { return x > y ? x = y, 1 : 0; }
templ inline void read(T &t) {
  t = 0;
  char f = 0, ch = getchar();
  double d = 0.1;
  while (ch > '9' || ch < '0')
    f |= (ch == '-'), ch = getchar();
  while (ch <= '9' && ch >= '0')
    t = t * 10 + ch - 48, ch = getchar();
  if (ch == '.') {
    ch = getchar();
    while (ch <= '9' && ch >= '0')
      t += d * (ch ^ 48), d *= 0.1, ch = getchar();
  }
  t = (f ? -t : t);
}
template <typename T, typename... Args> inline void read(T &t, Args &...args) {
  read(t);
  read(args...);
}
char __sr[1 << 21], __z[20];
int __C = -1, __zz = 0;
inline void Ot() { fwrite(__sr, 1, __C + 1, stdout), __C = -1; }
inline void print(register int x) {
  if (__C > 1 << 20)
    Ot();
  if (x < 0)
    __sr[++__C] = '-', x = -x;
  while (__z[++__zz] = x % 10 + 48, x /= 10)
    ;
  while (__sr[++__C] = __z[__zz], --__zz)
    ;
  __sr[++__C] = '\n';
}
void file() {
#ifdef NTFOrz
  freopen("a.in", "r", stdin);
#endif
}
inline void chktime() {
#ifdef NTFOrz
  cout << (clock() - t) / 1000.0 << '\n';
#endif
}
#ifdef mod
ll ksm(ll x, int y) {
  ll ret = 1;
  for (; y; y >>= 1, x = x * x % mod)
    if (y & 1)
      ret = ret * x % mod;
  return ret;
}
ll inv(ll x) { return ksm(x, mod - 2); }
#else
ll ksm(ll x, int y) {
  ll ret = 1;
  for (; y; y >>= 1, x = x * x)
    if (y & 1)
      ret = ret * x;
  return ret;
}
#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll
//ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
} // namespace my_std
using namespace my_std;

int n;
ll a[sz];

ll f[sz], g[sz];
int w[sz], sum[sz];
ll S[sz];
void work(ll *f) {
  rep(i, 1, n - 1) {
    ll x = a[i], y = a[i + 1], w = 0;
    while (x < a[i + 1])
      x *= 4, ++w;
    while (a[i] >= y * 4)
      y *= 4, --w;
    ::w[i] = w;
    sum[i] = sum[i - 1] + w;
    S[i] = S[i - 1] + w * i;
  }
  stack<pii> s;
  s.push(MP(-1, INT_MAX));
  s.push(MP(0, 0));
  rep(i, 1, n - 1) {
    while (sum[i] >= s.top().sec)
      s.pop();
    int j = s.top().fir;
    f[i] = S[i] - S[j + 1] - 1ll * (j + 1) * (sum[i] - sum[j + 1]);
    if (j > 0)
      f[i] += f[j];
    s.push(MP(i, sum[i]));
  }
}

int main() {
  file();
  read(n);
  rep(i, 1, n) read(a[i]);
  work(f);
  reverse(a + 1, a + n + 1);
  work(g);
  reverse(g + 1, g + n + 1);
  ll ans = 1e18;
  rep(i, 0, n) chkmin(ans, i + 2 * (g[i + 2] + (i ? f[i - 1] : 0)));
  cout << ans;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
clock_t t = clock();
namespace my_std {
using namespace std;
#define pii pair<int, int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i, x, y) for (int i = (x); i <= (y); i++)
#define drep(i, x, y) for (int i = (x); i >= (y); i--)
#define go(x) for (int i = head[x]; i; i = edge[i].nxt)
#define templ template <typename T>
#define sz 201010
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l, T r) { return uniform_int_distribution<T>(l, r)(rng); }
templ inline bool chkmax(T &x, T y) { return x < y ? x = y, 1 : 0; }
templ inline bool chkmin(T &x, T y) { return x > y ? x = y, 1 : 0; }
templ inline void read(T &t) {
  t = 0;
  char f = 0, ch = getchar();
  double d = 0.1;
  while (ch > '9' || ch < '0')
    f |= (ch == '-'), ch = getchar();
  while (ch <= '9' && ch >= '0')
    t = t * 10 + ch - 48, ch = getchar();
  if (ch == '.') {
    ch = getchar();
    while (ch <= '9' && ch >= '0')
      t += d * (ch ^ 48), d *= 0.1, ch = getchar();
  }
  t = (f ? -t : t);
}
template <typename T, typename... Args> inline void read(T &t, Args &...args) {
  read(t);
  read(args...);
}
char __sr[1 << 21], __z[20];
int __C = -1, __zz = 0;
inline void Ot() { fwrite(__sr, 1, __C + 1, stdout), __C = -1; }
inline void print(register int x) {
  if (__C > 1 << 20)
    Ot();
  if (x < 0)
    __sr[++__C] = '-', x = -x;
  while (__z[++__zz] = x % 10 + 48, x /= 10)
    ;
  while (__sr[++__C] = __z[__zz], --__zz)
    ;
  __sr[++__C] = '\n';
}
void file() {
#ifdef NTFOrz
  freopen("a.in", "r", stdin);
#endif
}
inline void chktime() {
#ifdef NTFOrz
  cout << (clock() - t) / 1000.0 << '\n';
#endif
}
#ifdef mod
ll ksm(ll x, int y) {
  ll ret = 1;
  for (; y; y >>= 1, x = x * x % mod)
    if (y & 1)
      ret = ret * x % mod;
  return ret;
}
ll inv(ll x) { return ksm(x, mod - 2); }
#else
ll ksm(ll x, int y) {
  ll ret = 1;
  for (; y; y >>= 1, x = x * x)
    if (y & 1)
      ret = ret * x;
  return ret;
}
#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll
//ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
} // namespace my_std
using namespace my_std;

int n;
ll a[sz];

ll f[sz], g[sz];
int w[sz], sum[sz];
ll S[sz];
void work(ll *f) {
  rep(i, 1, n - 1) {
    ll x = a[i], y = a[i + 1], w = 0;
    while (x < a[i + 1])
      x *= 4, ++w;
    while (a[i] >= y * 4)
      y *= 4, --w;
    ::w[i] = w;
    sum[i] = sum[i - 1] + w;
    S[i] = S[i - 1] + w * i;
  }
  stack<pii> s;
  s.push(MP(-1, INT_MAX));
  s.push(MP(0, 0));
  rep(i, 1, n - 1) {
    while (sum[i] >= s.top().sec)
      s.pop();
    int j = s.top().fir;
    f[i] = S[i] - S[j + 1] - 1ll * (j + 1) * (sum[i] - sum[j + 1]);
    if (j > 0)
      f[i] += f[j];
    s.push(MP(i, sum[i]));
  }
}

int main() {
  file();
  read(n);
  rep(i, 1, n) read(a[i]);
  work(f);
  reverse(a + 1, a + n + 1);
  work(g);
  reverse(g + 1, g + n + 1);
  ll ans = 1e18;
  rep(i, 0, n) chkmin(ans, i + 2 * (g[i + 2] + (i ? f[i - 1] : 0)));
  cout << ans;
  return 0;
}