Problem p01703 (C++) — buggy submission, verdict: Time Limit Exceeded

/* --- author: dxm --- */
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;

#define INF 1e9
#define Inf 1e18
#define rep(i, n) for (int(i) = 0; (i) < n; i++)
#define REP(i, n) for (int(i) = 1; (i) <= n; i++)
#define mp make_pair
#define pb push_back
#define fst first
#define snd second
typedef long long ll;
typedef double db;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;

void qread(int &x) {
  int neg = 1;
  x = 0;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      neg = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    x = 10 * x + c - '0', c = getchar();
  x *= neg;
}

const int maxn = 100005;
int n, m;
db p[maxn], q[maxn], dp[maxn];
int len[maxn];

int main() {
#ifdef FILE
  freopen("FILE.in", "r", stdin);
  freopen("FILE.out", "w", stdout);
#endif
  while (scanf("%d", &n) && n > 0) {
    m = 0;
    REP(i, n) {
      scanf("%lf", &p[i]);
      if (m && p[i] > 0.999 && q[m] > 0.999)
        len[m]++;
      else
        q[++m] = p[i], len[m] = 1;
    }
    dp[m + 1] = 0;
    for (int i = m; i >= 1; i--) {
      db cur = 0;
      dp[i] = INF;
      for (int j = i; j <= i + 100 && j <= m; j++) {
        cur *= 1 / q[j];
        cur += len[j] * (1 / q[j]);
        dp[i] = min(dp[i], cur + dp[j + 1]);
      }
      dp[i]++;
    }
    printf("%.10lf\\n", dp[1] - 1.0);
  }
#ifdef TIME
  printf("Running Time = %d ms\\n", int(clock() * 1000.0 / CLOCKS_PER_SEC));
#endif
  return 0;
}

/*
Input:
-----------------
Output:
*/


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define iinf 2000000000
#define linf 1000000000000000000LL
#define ulinf 10000000000000000000ull
#define MOD1 1000000007LL
#define mpr make_pair
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned long UL;
typedef unsigned short US;
typedef pair<int, int> pii;
clock_t __stt;
inline void TStart() { __stt = clock(); }
inline void TReport() {
  printf("\\nCurrent Case Taken Time : %.3lf sec\\n",
         (double)(clock() - __stt) / CLOCKS_PER_SEC);
}
template <typename T> T MIN(T a, T b) { return a < b ? a : b; }
template <typename T> T MAX(T a, T b) { return a > b ? a : b; }
template <typename T> T ABS(T a) { return a > 0 ? a : (-a); }
template <typename T> void UMIN(T &a, T b) {
  if (b < a)
    a = b;
}
template <typename T> void UMAX(T &a, T b) {
  if (b > a)
    a = b;
}
int n, stk[200005], lp, rp;
double p[100005], dp[100005];
double trans(int F, int T) {
  int i;
  double cur = 1, ret = 0;
  for (i = T - 1; i >= F; --i) {
    cur /= p[i];
    ret += cur;
    if (ret > 1e18)
      return 1e18 + 5;
  }
  return dp[F] + 1.0 + ret;
}
int overtake(int A, int B) {
  int i;
  double vA = 0, vB = trans(B, A);
  for (i = A + 1; i < n; ++i) {
    vA = (vA + 1.0) / p[i - 1];
    vB = (vB + 1.0) / p[i - 1];
    UMIN(vB, 1e18 + 5);
    if (vA > 1e18)
      return n;
    if (vA < vB)
      return i;
  }
  return n;
}
void solve() {
  // inputting start
  // 变量名不要写重写混！
  int i, j, k;
  scanf("%d", &n);
  ++n;
  if (n == 1)
    exit(0);
  for (i = 0; i < n - 1; ++i) {
    scanf("%lf", p + i);
  }
#ifdef LOCAL
  TStart();
#endif
  // calculation start
  // 变量名不要写重写混！
  lp = 100002;
  rp = 100003;
  stk[lp] = 0;
  dp[0] = 0;
  for (i = 1; i < n; ++i) {
    while (rp > lp + 1) {
      int L = stk[rp - 2], R = stk[rp - 1];
      double F = trans(R, i);
      if (F >= trans(L, i) || F >= 1e18)
        --rp;
      else
        break;
    }
    dp[i] = trans(stk[rp - 1], i);
    while (rp > lp + 1) {
      int L = stk[lp], M = stk[lp + 1];
      if (overtake(i, L) <= overtake(L, M))
        ++lp;
      else
        break;
    }
    if (overtake(i, stk[lp]) < n)
      stk[--lp] = i;
  }
  printf("%.10lf\\n", dp[n - 1] - 1.0);
#ifdef LOCAL
  TReport();
#endif
}
int main() {
  while (1)
    solve();
  return 0;
}