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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const double EPS = 1.0e-10;
const int MOD = 100000007;

void combination(int n, vector<vector<int>> &comb) {
  comb.assign(n + 1, vector<int>(n + 1, 0));
  for (int i = 0; i <= n; ++i) {
    comb[i][0] = 1;
    for (int j = 1; j <= i; ++j) {
      comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
      comb[i][j] %= MOD;
    }
  }
}

vector<double> destroy(1001, 0.0); // 破壊されるまでの時間の期待値

double solve(vector<double> &p, vector<double> &q, int &pattern) {
  int n = p.size();

  double t = 0.0;
  for (int i = 0; i < n; ++i)
    t += destroy[q[i] * 1000 + EPS];

  double ret = DBL_MAX;
  pattern = 0;
  for (int i = 0; i < n; ++i) {
    double t2 = t - destroy[q[i] * 1000 + EPS] + destroy[p[i] * 1000 + EPS];
    if (t2 < ret - EPS) {
      ret = t2;
      pattern = 1;
    } else if (t2 < ret + EPS) {
      ++pattern;
    }
  }

  return ret;
}

int main() {
  for (int i = 1; i <= 1000; ++i) {
    double p = i / 1000.0;
    double a = 1.0;
    for (int j = 1;; ++j) {
      if (a * p * j < EPS / 1000)
        break;
      destroy[i] += a * p * j;
      a *= 1.0 - p;
    }
  }

  vector<vector<int>> comb;
  combination(100, comb);

  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      return 0;

    vector<double> p(n), q(n);
    vector<int> id(n);
    for (int i = 0; i < n; ++i)
      cin >> p[i] >> id[i] >> q[i];

    vector<bool> check(n, false);
    double ret = 0.0;
    long long pattern = 1;
    int tmp = n;
    for (int i = 0; i < n; ++i) {
      if (check[i])
        continue;

      int j = i;
      vector<double> p2, q2;
      while (!check[j]) {
        p2.push_back(p[j]);
        q2.push_back(q[j]);
        check[j] = true;
        j = id[j];
      }

      int pattern2;
      ret += solve(p2, q2, pattern2);
      pattern *= pattern2;
      pattern %= MOD;

      pattern *= comb[tmp][p2.size()];
      pattern %= MOD;
      tmp -= p2.size();
    }

    printf("%.10f %d\\n", ret, (int)pattern);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const double EPS = 1.0e-10;
const int MOD = 100000007;

void combination(int n, vector<vector<int>> &comb) {
  comb.assign(n + 1, vector<int>(n + 1, 0));
  for (int i = 0; i <= n; ++i) {
    comb[i][0] = 1;
    for (int j = 1; j <= i; ++j) {
      comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
      comb[i][j] %= MOD;
    }
  }
}

vector<double> destroy(1001, 0.0); // 破壊されるまでの時間の期待値

double solve(vector<double> &p, vector<double> &q, int &pattern) {
  int n = p.size();

  double t = 0.0;
  for (int i = 0; i < n; ++i)
    t += destroy[q[i] * 1000 + EPS];

  double ret = DBL_MAX;
  pattern = 0;
  for (int i = 0; i < n; ++i) {
    double t2 = t - destroy[q[i] * 1000 + EPS] + destroy[p[i] * 1000 + EPS];
    if (t2 < ret - EPS) {
      ret = t2;
      pattern = 1;
    } else if (t2 < ret + EPS) {
      ++pattern;
    }
  }

  return ret;
}

int main() {
  for (int i = 1; i <= 1000; ++i) {
    double p = i / 1000.0;
    double a = 1.0;
    for (int j = 1; j <= 50000; ++j) {
      destroy[i] += a * p * j;
      a *= 1.0 - p;
    }
  }

  vector<vector<int>> comb;
  combination(100, comb);

  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      return 0;

    vector<double> p(n), q(n);
    vector<int> id(n);
    for (int i = 0; i < n; ++i)
      cin >> p[i] >> id[i] >> q[i];

    vector<bool> check(n, false);
    double ret = 0.0;
    long long pattern = 1;
    int tmp = n;
    for (int i = 0; i < n; ++i) {
      if (check[i])
        continue;

      int j = i;
      vector<double> p2, q2;
      while (!check[j]) {
        p2.push_back(p[j]);
        q2.push_back(q[j]);
        check[j] = true;
        j = id[j];
      }

      int pattern2;
      ret += solve(p2, q2, pattern2);
      pattern *= pattern2;
      pattern %= MOD;

      pattern *= comb[tmp][p2.size()];
      pattern %= MOD;
      tmp -= p2.size();
    }

    printf("%.10f %d\\n", ret, (int)pattern);
  }
}