Problem:
Problem H: World domination
世界征服を企む悪の組織、なんてものは、古今東西フィクションノンフィクションを問わず、いろんな所にいるものだが、一体彼らは何のために世界征服をしようとしたのだろうか。そんなことをふと考えてしまうのは、私もまた、世界征服を企てているからであった。私が世界征服を目論む理由はただ一つ、私がロボット工学の分野で世界一優秀であることを世界に示すためである。征服したあとの世界になど興味はない、そこらへんの犬にでもくれてやっても構わないのだ。
誠に遺憾だが、それはつまり、私よりも優秀であるとされている研究者がいる、ということだ。その人物には心当たりがある。誰あろう、私の学生時代の同期 R 博士である。彼の実績は認めるが、しかし私のそれより優れていたとは思わない。ただ彼は、平和のためのロボット利用などという甘っちょろいことを言っていたがために、教授連中の受けが良かったのだ。主席こそ逃したものの、本当は私の方がずっと優秀なのだ。
その優秀さを示す端的な例が、この世界征服のために用意した戦闘ロボットである。戦闘ロボットはその特性に応じた専用の武器を持ち、その武器はチップに収められているが、このチップは強力な互換性を持つ。ただ開発者自身の他の戦闘ロボットと互換性をもつだけではない (その程度のことは、他ならぬ R 博士が既に達成している) 。私のチップのすごいところは、その R 博士の家事手伝いロボットとも互換性があるのだ。その家事手伝いロボットは非売品のワンオフモデルなので、私はそのロボットの設計を知らないで互換チップを開発したのだ。我ながら神業と言わざるを得ない。この仕様を敵が利するだけの無駄な仕様と言う人もいるが、それは愚かな考え方だ。私は私の優秀さを示すために戦闘ロボットを開発しているのだ。ただ勝てばいいというものではないのである。
世界征服計画に話を戻そう。私は n 機の戦闘ロボットを製作し、それぞれに異なる武器チップを 1 つずつインストールした。これを用いて世界の主要施設を奪取するつもりだが、この計画を阻むために R 博士は彼の家事手伝いロボットを送り込んでくることだろう。家事手伝いロボットは自身の武器で私の戦闘ロボットに戦闘を挑んでくるが、1 回の戦闘には 1 単位時間かかり、戦闘の結果どちらか片方のロボットが敗北し破壊される。
戦闘の結果私のロボットが破壊された場合、そのロボットの武器チップは相手に奪われることになる。ある私のロボットの武器チップは他の私のロボットのうちの 1 機の弱点になっていて、またどの私のロボットも弱点となる武器チップをただ 1 つだけ持つ。私は私の各ロボットについて、相手がそのロボットの弱点武器を持っていた場合の敗北確率・持っていなかった場合の敗北確率をそれぞれ見積もることができる。
戦闘の結果相手の家事手伝いロボットが破壊された場合、R 博士はスペアボディ転送システムによって同じ家事手伝いロボットを送り込んでくる。このとき、相手のロボットが既に得ていた武器チップは失われることがない。R 博士は無制限にスペアボディ転送システムを使用してくるが、その隙に私は私の戦闘ロボットを修理することができるので、何度戦っても先に説明した敗北確率は変化することはない。また、スペアボディ転送システムは家事手伝いロボットが破壊されたときに破壊された場所でしか使えないので、家事手伝いロボットは敗北した直後に別の私の戦闘ロボットに挑むことはできない。
R 博士は無制限にスペアボディ転送システムを使えるのだから、悔しいが n 機の戦闘ロボットが全て破壊されるのは時間の問題だ。そこで私は戦闘ロボットを戦わせている裏で、スペアボディ転送システムごと破壊できるようなさらなるロボットの開発に勤しむつもりだ。しかし、私には一体どれだけの時間が残されているのだろうか。R 博士のロボットが最も早く私の n 機のロボットを撃破するような戦略を取ったとき、どれだけの時間がかかるだろうか。まずはそれを計算しなければなるまい。ついでに、そのようなロボットの撃破順序が何通りあるかも確認しておきたい。
Input
入力は複数のケースからなる。
各ケースは以下のフォーマットで与えられる。
n
p
0
id
0
w
0
p
1
id
1
w
1
.
.
.
p
1
id
n-1
w
n-1
p
i
は弱点の武器を相手が持っていない時に
i
番目の戦闘ロボットが敗北する確率を表す。
id
i
は
i
番目の戦闘ロボットの弱点となる武器を持っている戦闘ロボットを表す。
w
i
は弱点の武器を相手が持っている時に
i
番目の戦闘ロボットが敗北する確率を表す。
入力の終わりは
n
= 0によって与えられる。
各値は以下の条件を満たす
2 ≤ n ≤ 100
p
i
と
w
i
は小数点以下3桁の数で表される。
0.001 ≤
p
i
<
w
i
≤ 1.000
id
i
!=
i
テストケースの数は500を超えない。
Output
n体の戦闘ロボットが撃破されるまでの時間の期待値と、その撃破順序の組み合わせの数を100000007で割った余りを空白で区切って出力せよ。
期待値の値はジャッジの用意した回答との誤差1e-9までが認められる。
Sample input
4
0.200 3 0.500
0.100 0 0.400
0.900 1 1.000
0.400 2 0.600
2
0.600 1 0.800
0.500 0 1.000
9
0.200 7 0.600
0.400 0 0.500
0.700 8 1.000
0.100 4 0.400
0.200 2 0.600
0.100 6 0.400
0.100 5 0.400
0.600 3 0.900
0.500 1 0.900
9
0.300 8 0.900
0.700 3 0.800
0.300 0 0.900
0.700 6 0.800
0.200 5 0.700
0.200 2 0.700
0.700 4 0.800
0.700 1 0.800
0.300 7 0.900
0
Sample output
7.27777777778 1
2.66666666667 1
23.98412698413 72
11.36904761905 4
The University of Aizu Programming Contest 2011 Summer
原案: Tomoya Sakai
問題文: Takashi Tayama

Submitted solutions:

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class t>
using table = vector<vector<t>>;
const ld eps = 1e-10;

// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"
  
struct robot {
	ld n_loss;
	int id;
	ld s_loss;
};

struct Dscc {
public:

	//fst:belongs , scd:newedges
	pair<vector<vector<int>>, vector<vector<int>>>get(const vector<vector<int>>&edges) {
		nums.resize(edges.size());
		fill(nums.begin(), nums.end(), -1);
		vector<vector<int>>revedges(edges.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				revedges[j].push_back(i);
			}
		}
		int num = 0;
		for (int i = 0; i < edges.size(); ++i) {
			dfs(i, num, edges);
		}
		vector<int>big(nums.size());
		for (int i = 0; i < nums.size(); ++i) {
			big[nums[i]] = i;
		}
		reverse(big.begin(), big.end());
		unis.resize(edges.size());
		fill(unis.begin(), unis.end(), -1);
		num = 0;
		for (int i = 0; i < big.size(); ++i) {

			dfs2(big[i], num, revedges);
			num++;
		}
		vector<int>nums;
		for (int i = 0; i < unis.size(); ++i) {
			nums.push_back(unis[i]);
		}
		sort(nums.begin(), nums.end());
		nums.erase(unique(nums.begin(), nums.end()), nums.end());


		map<int, int>mp;
		for (int i = 0; i < nums.size(); ++i) {
			mp[nums[i]] = i;
		}
		for (int i = 0; i < unis.size(); ++i) {
			unis[i] = mp[unis[i]];
		}

		vector<vector<int>>belongs(nums.size());
		for (int i = 0; i < unis.size(); ++i) {
			belongs[unis[i]].push_back(i);
		}
		vector<vector<int>>newedges(nums.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				if (unis[i] != unis[j]) {
					newedges[unis[i]].push_back(unis[j]);
				}
			}
		}
		return make_pair(belongs, newedges);
	}
private:
	vector<int>nums;
	vector<int>unis;


	void dfs(const int id, int &num, const vector<vector<int>>&edges) {
		if (nums[id] != -1)return;
		else {
			nums[id] = -2;
			for (auto i : edges[id]) {
				dfs(i, num, edges);
			}
		}
		nums[id] = num++;
		return;
	}
	void dfs2(const int id, const int &num, const vector<vector<int>>&edges) {
		if (unis[id] != -1)return;
		else {
			unis[id] = -2;
			for (auto i : edges[id])
				dfs2(i, num, edges);
		}
		unis[id] = num;
		return;
	}

}dscc;



const int mod = 100000007;
struct Mod {
public:
	int num;
	Mod() : Mod(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) {
		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
	}
	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator+(const Mod a, const long long int  b) { return b + a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const long long  int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	return Mod(a) / b;
}
Mod operator/=(Mod &a, const Mod b) {
	return a = a / b;
}

#define MAX_MOD_N 10240

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init(const int amax = MAX_MOD_N) {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < amax - 1; ++i) { 
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}

int main() {
	cout << setprecision(11) << fixed;
	init();
	while (1) {
		int N; cin >> N;

		if (!N)break;
		vector<robot>robs;
		vector<vector<int>>edges(N);
		for (int i = 0; i < N; ++i) {
			ld a, c; int b; cin >> a >> b >> c;
			robs.push_back(robot{ a,b,c });
			edges[i].push_back(b);
		}

		auto p = dscc.get(edges);
		ld totalans = 0;
		Mod  totalsum = 1;
		int anum = N;
		for (int k = 0;k < p.first.size(); ++k) {
			ld ans = 1e8;
			Mod sum =1;
			for (int astart = 0; astart < p.first[k].size(); ++astart) {
				int start = p.first[k][astart];
				ld nans = 1 / (robs[start].n_loss);
				int next = robs[start].id;
				for (int j = 0; j < p.first[k].size() - 1; ++j) {
					nans += 1 / (robs[next].s_loss);
					next = robs[next].id;
				}
				if (nans + eps < ans) {
					ans = nans; sum = 1;
				}
				else if (abs(nans - ans) < eps) {
					sum+=1;
				}
				else {
					continue;
				}
			}
			totalans += ans;
			totalsum *= sum;

			totalsum *= comb(anum, p.first[k].size());
			anum -= p.first[k].size();
		}
		
		cout << totalans << " " << totalsum << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3320
final_rank: 12

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class t>
using table = vector<vector<t>>;
const ld eps = 1e-10;

// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"
  
struct robot {
	ld n_loss;
	int id;
	ld s_loss;
};

struct Dscc {
public:

	//fst:belongs , scd:newedges
	pair<vector<vector<int>>, vector<vector<int>>>get(const vector<vector<int>>&edges) {
		nums.resize(edges.size());
		fill(nums.begin(), nums.end(), -1);
		vector<vector<int>>revedges(edges.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				revedges[j].push_back(i);
			}
		}
		int num = 0;
		for (int i = 0; i < edges.size(); ++i) {
			dfs(i, num, edges);
		}
		vector<int>big(nums.size());
		for (int i = 0; i < nums.size(); ++i) {
			big[nums[i]] = i;
		}
		reverse(big.begin(), big.end());
		unis.resize(edges.size());
		fill(unis.begin(), unis.end(), -1);
		num = 0;
		for (int i = 0; i < big.size(); ++i) {

			dfs2(big[i], num, revedges);
			num++;
		}
		vector<int>nums;
		for (int i = 0; i < unis.size(); ++i) {
			nums.push_back(unis[i]);
		}
		sort(nums.begin(), nums.end());
		nums.erase(unique(nums.begin(), nums.end()), nums.end());


		map<int, int>mp;
		for (int i = 0; i < nums.size(); ++i) {
			mp[nums[i]] = i;
		}
		for (int i = 0; i < unis.size(); ++i) {
			unis[i] = mp[unis[i]];
		}

		vector<vector<int>>belongs(nums.size());
		for (int i = 0; i < unis.size(); ++i) {
			belongs[unis[i]].push_back(i);
		}
		vector<vector<int>>newedges(nums.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				if (unis[i] != unis[j]) {
					newedges[unis[i]].push_back(unis[j]);
				}
			}
		}
		return make_pair(belongs, newedges);
	}
private:
	vector<int>nums;
	vector<int>unis;


	void dfs(const int id, int &num, const vector<vector<int>>&edges) {
		if (nums[id] != -1)return;
		else {
			nums[id] = -2;
			for (auto i : edges[id]) {
				dfs(i, num, edges);
			}
		}
		nums[id] = num++;
		return;
	}
	void dfs2(const int id, const int &num, const vector<vector<int>>&edges) {
		if (unis[id] != -1)return;
		else {
			unis[id] = -2;
			for (auto i : edges[id])
				dfs2(i, num, edges);
		}
		unis[id] = num;
		return;
	}

}dscc;



const int mod = 1000000007;
struct Mod {
public:
	int num;
	Mod() : Mod(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) {
		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
	}
	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator+(const Mod a, const long long int  b) { return b + a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const long long  int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	return Mod(a) / b;
}
Mod operator/=(Mod &a, const Mod b) {
	return a = a / b;
}

#define MAX_MOD_N 1024000

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init(const int amax = MAX_MOD_N) {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < amax - 1; ++i) {
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}

int main() {
	cout << setprecision(11) << fixed;
	init();
	while (1) {
		int N; cin >> N;

		if (!N)break;
		vector<robot>robs;
		vector<vector<int>>edges(N);
		for (int i = 0; i < N; ++i) {
			ld a, c; int b; cin >> a >> b >> c;
			robs.push_back(robot{ a,b,c });
			edges[i].push_back(b);
		}

		auto p = dscc.get(edges);
		ld totalans = 0;
		Mod  totalsum = 1;
		int anum = N;
		for (int k = 0;k < p.first.size(); ++k) {
			ld ans = 1e8;
			Mod sum =1;
			for (int astart = 0; astart < p.first[k].size(); ++astart) {
				int start = p.first[k][astart];
				ld nans = 1 / (robs[start].n_loss);
				int next = robs[start].id;
				for (int j = 0; j < p.first[k].size() - 1; ++j) {
					nans += 1 / (robs[next].s_loss);
					next = robs[next].id;
				}
				if (nans + eps < ans) {
					ans = nans; sum = 1;
				}
				else if (abs(nans - ans) < eps) {
					sum+=1;
				}
				else {
					continue;
				}
			}
			totalans += ans;
			totalsum *= sum;

			totalsum *= comb(anum, p.first[k].size());
			anum -= p.first[k].size();
		}
		
		cout << totalans << " " << totalsum << endl;
	}
	return 0;
}
accuracy: 0.6666666666666666
time_ms: 320
memory_kb: 11272
final_rank: 17

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class t>
using table = vector<vector<t>>;
const ld eps = 1e-6;

// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"
  
struct robot {
	ld n_loss;
	int id;
	ld s_loss;
};

struct Dscc {
public:

	//fst:belongs , scd:newedges
	pair<vector<vector<int>>, vector<vector<int>>>get(const vector<vector<int>>&edges) {
		nums.resize(edges.size());
		fill(nums.begin(), nums.end(), -1);
		vector<vector<int>>revedges(edges.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				revedges[j].push_back(i);
			}
		}
		int num = 0;
		for (int i = 0; i < edges.size(); ++i) {
			dfs(i, num, edges);
		}
		vector<int>big(nums.size());
		for (int i = 0; i < nums.size(); ++i) {
			big[nums[i]] = i;
		}
		reverse(big.begin(), big.end());
		unis.resize(edges.size());
		fill(unis.begin(), unis.end(), -1);
		num = 0;
		for (int i = 0; i < big.size(); ++i) {

			dfs2(big[i], num, revedges);
			num++;
		}
		vector<int>nums;
		for (int i = 0; i < unis.size(); ++i) {
			nums.push_back(unis[i]);
		}
		sort(nums.begin(), nums.end());
		nums.erase(unique(nums.begin(), nums.end()), nums.end());


		map<int, int>mp;
		for (int i = 0; i < nums.size(); ++i) {
			mp[nums[i]] = i;
		}
		for (int i = 0; i < unis.size(); ++i) {
			unis[i] = mp[unis[i]];
		}

		vector<vector<int>>belongs(nums.size());
		for (int i = 0; i < unis.size(); ++i) {
			belongs[unis[i]].push_back(i);
		}
		vector<vector<int>>newedges(nums.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				if (unis[i] != unis[j]) {
					newedges[unis[i]].push_back(unis[j]);
				}
			}
		}
		return make_pair(belongs, newedges);
	}
private:
	vector<int>nums;
	vector<int>unis;


	void dfs(const int id, int &num, const vector<vector<int>>&edges) {
		if (nums[id] != -1)return;
		else {
			nums[id] = -2;
			for (auto i : edges[id]) {
				dfs(i, num, edges);
			}
		}
		nums[id] = num++;
		return;
	}
	void dfs2(const int id, const int &num, const vector<vector<int>>&edges) {
		if (unis[id] != -1)return;
		else {
			unis[id] = -2;
			for (auto i : edges[id])
				dfs2(i, num, edges);
		}
		unis[id] = num;
		return;
	}

}dscc;



const int mod = 1000000007;
struct Mod {
public:
	int num;
	Mod() : Mod(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) {
		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
	}
	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator+(const Mod a, const long long int  b) { return b + a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const long long  int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	return Mod(a) / b;
}
Mod operator/=(Mod &a, const Mod b) {
	return a = a / b;
}

#define MAX_MOD_N 1024000

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init(const int amax = MAX_MOD_N) {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < amax - 1; ++i) {
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}

int main() {
	cout << setprecision(11) << fixed;
	init();
	while (1) {
		int N; cin >> N;

		if (!N)break;
		vector<robot>robs;
		vector<vector<int>>edges(N);
		for (int i = 0; i < N; ++i) {
			ld a, c; int b; cin >> a >> b >> c;
			robs.push_back(robot{ a,b,c });
			edges[i].push_back(b);
		}

		auto p = dscc.get(edges);
		ld totalans = 0;
		Mod  totalsum = 1;
		int anum = N;
		for (int k = 0;k < p.first.size(); ++k) {
			ld ans = 1e8;
			Mod sum =1;
			for (int astart = 0; astart < p.first[k].size(); ++astart) {
				int start = p.first[k][astart];
				ld nans = 1 / (robs[start].n_loss);
				int next = robs[start].id;
				for (int j = 0; j < p.first[k].size() - 1; ++j) {
					nans += 1 / (robs[next].s_loss);
					next = robs[next].id;
				}
				if (nans + eps < ans) {
					ans = nans; sum = 1;
				}
				else if (abs(nans - ans) < eps) {
					sum+=1;
				}
				else {
					continue;
				}
			}
			totalans += ans;
			totalsum *= sum;

			totalsum *= comb(anum, p.first[k].size());
			anum -= p.first[k].size();
		}
		
		cout << totalans << " " << totalsum << endl;
	}
	return 0;
}
accuracy: 0.6666666666666666
time_ms: 330
memory_kb: 11296
final_rank: 20

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class t>
using table = vector<vector<t>>;
const ld eps = 1e-6;

// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"
  
struct robot {
	ld n_loss;
	int id;
	ld s_loss;
};

struct Dscc {
public:

	//fst:belongs , scd:newedges
	pair<vector<vector<int>>, vector<vector<int>>>get(const vector<vector<int>>&edges) {
		nums.resize(edges.size());
		fill(nums.begin(), nums.end(), -1);
		vector<vector<int>>revedges(edges.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				revedges[j].push_back(i);
			}
		}
		int num = 0;
		for (int i = 0; i < edges.size(); ++i) {
			dfs(i, num, edges);
		}
		vector<int>big(nums.size());
		for (int i = 0; i < nums.size(); ++i) {
			big[nums[i]] = i;
		}
		reverse(big.begin(), big.end());
		unis.resize(edges.size());
		fill(unis.begin(), unis.end(), -1);
		num = 0;
		for (int i = 0; i < big.size(); ++i) {

			dfs2(big[i], num, revedges);
			num++;
		}
		vector<int>nums;
		for (int i = 0; i < unis.size(); ++i) {
			nums.push_back(unis[i]);
		}
		sort(nums.begin(), nums.end());
		nums.erase(unique(nums.begin(), nums.end()), nums.end());


		map<int, int>mp;
		for (int i = 0; i < nums.size(); ++i) {
			mp[nums[i]] = i;
		}
		for (int i = 0; i < unis.size(); ++i) {
			unis[i] = mp[unis[i]];
		}

		vector<vector<int>>belongs(nums.size());
		for (int i = 0; i < unis.size(); ++i) {
			belongs[unis[i]].push_back(i);
		}
		vector<vector<int>>newedges(nums.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				if (unis[i] != unis[j]) {
					newedges[unis[i]].push_back(unis[j]);
				}
			}
		}
		return make_pair(belongs, newedges);
	}
private:
	vector<int>nums;
	vector<int>unis;


	void dfs(const int id, int &num, const vector<vector<int>>&edges) {
		if (nums[id] != -1)return;
		else {
			nums[id] = -2;
			for (auto i : edges[id]) {
				dfs(i, num, edges);
			}
		}
		nums[id] = num++;
		return;
	}
	void dfs2(const int id, const int &num, const vector<vector<int>>&edges) {
		if (unis[id] != -1)return;
		else {
			unis[id] = -2;
			for (auto i : edges[id])
				dfs2(i, num, edges);
		}
		unis[id] = num;
		return;
	}

}dscc;



const int mod = 1000000007;
struct Mod {
public:
	int num;
	Mod() : Mod(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) {
		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
	}
	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator+(const Mod a, const long long int  b) { return b + a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const long long  int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	return Mod(a) / b;
}
Mod operator/=(Mod &a, const Mod b) {
	return a = a / b;
}

#define MAX_MOD_N 1024000

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init(const int amax = MAX_MOD_N) {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < amax - 1; ++i) {
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}

int main() {
	cout << setprecision(11) << fixed;
	init();
	while (1) {
		int N; cin >> N;

		if (!N)break;
		vector<robot>robs;
		vector<vector<int>>edges(N);
		for (int i = 0; i < N; ++i) {
			ld a, c; int b; cin >> a >> b >> c;
			robs.push_back(robot{ a,b,c });
			edges[i].push_back(b);
		}

		auto p = dscc.get(edges);
		ld totalans = 0;
		Mod  totalsum = 1;
		int anum = N;
		for (int k = 0;k < p.first.size(); ++k) {
			ld ans = 1e8;
			Mod sum = 0;
			for (int astart = 0; astart < p.first[k].size(); ++astart) {
				int start = p.first[k][astart];
				ld nans = 1 / (robs[start].n_loss);
				int next = robs[start].id;
				for (int j = 0; j < p.first[k].size() - 1; ++j) {
					nans += 1 / (robs[next].s_loss);
					next = robs[next].id;
				}
				if (nans + eps < ans) {
					ans = nans; sum = 1;
				}
				else if (abs(nans - ans) < eps) {
					sum+=1;
				}
				else {
					continue;
				}
			}
			totalans += ans;
			totalsum *= sum;

			totalsum *= comb(anum, p.first[k].size());
			anum -= p.first[k].size();
		}
		
		cout << totalans << " " << totalsum << endl;
	}
	return 0;
}
accuracy: 0.6666666666666666
time_ms: 320
memory_kb: 11304
final_rank: 18

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class t>
using table = vector<vector<t>>;
const ld eps = 1e-7;

// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"
  
struct robot {
	ld n_loss;
	int id;
	ld s_loss;
};

struct Dscc {
public:

	//fst:belongs , scd:newedges
	pair<vector<vector<int>>, vector<vector<int>>>get(const vector<vector<int>>&edges) {
		nums.resize(edges.size());
		fill(nums.begin(), nums.end(), -1);
		vector<vector<int>>revedges(edges.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				revedges[j].push_back(i);
			}
		}
		int num = 0;
		for (int i = 0; i < edges.size(); ++i) {
			dfs(i, num, edges);
		}
		vector<int>big(nums.size());
		for (int i = 0; i < nums.size(); ++i) {
			big[nums[i]] = i;
		}
		reverse(big.begin(), big.end());
		unis.resize(edges.size());
		fill(unis.begin(), unis.end(), -1);
		num = 0;
		for (int i = 0; i < big.size(); ++i) {

			dfs2(big[i], num, revedges);
			num++;
		}
		vector<int>nums;
		for (int i = 0; i < unis.size(); ++i) {
			nums.push_back(unis[i]);
		}
		sort(nums.begin(), nums.end());
		nums.erase(unique(nums.begin(), nums.end()), nums.end());


		map<int, int>mp;
		for (int i = 0; i < nums.size(); ++i) {
			mp[nums[i]] = i;
		}
		for (int i = 0; i < unis.size(); ++i) {
			unis[i] = mp[unis[i]];
		}

		vector<vector<int>>belongs(nums.size());
		for (int i = 0; i < unis.size(); ++i) {
			belongs[unis[i]].push_back(i);
		}
		vector<vector<int>>newedges(nums.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				if (unis[i] != unis[j]) {
					newedges[unis[i]].push_back(unis[j]);
				}
			}
		}
		return make_pair(belongs, newedges);
	}
private:
	vector<int>nums;
	vector<int>unis;


	void dfs(const int id, int &num, const vector<vector<int>>&edges) {
		if (nums[id] != -1)return;
		else {
			nums[id] = -2;
			for (auto i : edges[id]) {
				dfs(i, num, edges);
			}
		}
		nums[id] = num++;
		return;
	}
	void dfs2(const int id, const int &num, const vector<vector<int>>&edges) {
		if (unis[id] != -1)return;
		else {
			unis[id] = -2;
			for (auto i : edges[id])
				dfs2(i, num, edges);
		}
		unis[id] = num;
		return;
	}

}dscc;



const int mod = 1000000007;
struct Mod {
public:
	int num;
	Mod() : Mod(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) {
		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
	}
	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator+(const Mod a, const long long int  b) { return b + a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const long long  int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	return Mod(a) / b;
}
Mod operator/=(Mod &a, const Mod b) {
	return a = a / b;
}

#define MAX_MOD_N 1024000

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init(const int amax = MAX_MOD_N) {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < amax - 1; ++i) {
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}

int main() {
	cout << setprecision(11) << fixed;
	init();
	while (1) {
		int N; cin >> N;

		if (!N)break;
		vector<robot>robs;
		vector<vector<int>>edges(N);
		for (int i = 0; i < N; ++i) {
			ld a, c; int b; cin >> a >> b >> c;
			robs.push_back(robot{ a,b,c });
			edges[i].push_back(b);
		}

		auto p = dscc.get(edges);
		ld totalans = 0;
		Mod  totalsum = 1;
		int anum = N;
		for (int k = 0;k < p.first.size(); ++k) {
			ld ans = 1e8;
			Mod sum = 0;
			for (int astart = 0; astart < p.first[k].size(); ++astart) {
				int start = p.first[k][astart];
				ld nans = 1 / (robs[start].n_loss);
				int next = robs[start].id;
				for (int j = 0; j < p.first[k].size() - 1; ++j) {
					nans += 1 / (robs[next].s_loss);
					next = robs[next].id;
				}
				if (nans + eps < ans) {
					ans = nans; sum = 1;
				}
				else if (abs(nans - ans) < eps) {
					sum+=1;
				}
				else {
					continue;
				}
			}
			totalans += ans;
			totalsum *= sum;

			totalsum *= comb(anum, p.first[k].size());
			anum -= p.first[k].size();
		}
		
		cout << totalans << " " << totalsum << endl;
	}
	return 0;
}
accuracy: 0.6666666666666666
time_ms: 320
memory_kb: 11316
final_rank: 19

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
double p[110];
int q[110];
double r[110];
long long mod=100000007;
int v[110];
double eps=1e-9;
int C[110][110];
int main(){
	int a;
	C[0][0]=1;
	for(int i=0;i<106;i++){
		for(int j=0;j<=i;j++){
			C[i+1][j]=(C[i+1][j]+C[i][j])%mod;
			C[i+1][j+1]=(C[i+1][j+1]+C[i][j])%mod;
		}
	}
	while(scanf("%d",&a),a){
		for(int i=0;i<a;i++)scanf("%lf%d%lf",p+i,q+i,r+i);
		for(int i=0;i<a;i++)v[i]=0;
		long long ret=1;
		double val=0;
		int rem=a;
		for(int i=0;i<a;i++){
			if(v[i])continue;
			int at=i;
			double m=999999999;
			int cnt=0;
			int sz=0;
			while(!v[at]){
				v[at]=1;
				val+=1.0/r[at];
				if(m-eps>1.0/p[at]-1.0/r[at]){
					m=1.0/p[at]-1.0/r[at];
					cnt=1;
				}else if(m>1.0/p[at]-1.0/r[at]-eps){
					cnt++;
				}
				at=q[at];
				sz++;
			}
			ret=ret*cnt%mod;
			val+=m;
			ret=ret*C[rem][sz]%mod;
			rem-=sz;
		}
		printf("%.12f %lld\n",val,ret);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 1136
final_rank: 6

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
double p[110];
int q[110];
double r[110];
long long mod=1000000007;
int v[110];
double eps=1e-9;
int C[110][110];
int main(){
	int a;
	C[0][0]=1;
	for(int i=0;i<106;i++){
		for(int j=0;j<=i;j++){
			C[i+1][j]=(C[i+1][j]+C[i][j])%mod;
			C[i+1][j+1]=(C[i+1][j+1]+C[i][j])%mod;
		}
	}
	while(scanf("%d",&a),a){
		for(int i=0;i<a;i++)scanf("%lf%d%lf",p+i,q+i,r+i);
		for(int i=0;i<a;i++)v[i]=0;
		long long ret=1;
		double val=0;
		int rem=a;
		for(int i=0;i<a;i++){
			if(v[i])continue;
			int at=i;
			double m=999999999;
			int cnt=0;
			int sz=0;
			while(!v[at]){
				v[at]=1;
				val+=1.0/r[at];
				if(m-eps>1.0/p[at]-1.0/r[at]){
					m=1.0/p[at]-1.0/r[at];
					cnt=1;
				}else if(m>1.0/p[at]-1.0/r[at]-eps){
					cnt++;
				}
				at=q[at];
				sz++;
			}
			ret=ret*cnt%mod;
			val+=m;
			ret=ret*C[rem][sz]%mod;
			rem-=sz;
		}
		printf("%.12f %lld\n",val,ret);
	}
}
accuracy: 0.6666666666666666
time_ms: 10
memory_kb: 1136
final_rank: 13

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
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);
    }
}
accuracy: 1
time_ms: 30
memory_kb: 0
final_rank: 5

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
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<=30000; ++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);
    }
}
accuracy: 0.6666666666666666
time_ms: 520
memory_kb: 1040
final_rank: 15

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
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<=30000; ++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, pattern);
    }
}
accuracy: 0.6666666666666666
time_ms: 520
memory_kb: 1040
final_rank: 15

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
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<=30000; ++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 * comb[tmp][p2.size()];
            pattern %= MOD;
            tmp -= p2.size();
        }

        printf("%.10f %d\n", ret, pattern);
    }
}
accuracy: 0.6666666666666666
time_ms: 520
memory_kb: 1036
final_rank: 14

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;
const int M = 100000007;

int combi[500][500];

ll func(vector<int> v) {
  ll res = 1;
  int now = v[0];
  for (int i=1; i<v.size(); ++i) {
    res = (res * combi[v[i]+now][v[i]]) % M;
    now += v[i];
  }
  return res;
}

int main() {
  REP(i,500) combi[i][0] = 1;
  REP(i,500-1) REP(j,500-1) combi[i+1][j+1] = (combi[i][j+1]+combi[i][j]) % M;
  int n;
  while(cin>>n,n) {
    double p[n],q[n];
    int a[n], b[n];    
    REP(i,n) {
      cin>>p[i]>>a[i]>>q[i];
      b[a[i]] = i;
    }
    bool visited[n];
    memset(visited,0,sizeof(visited));
    vector<vector<int> > cycle;
    REP(i, n) {
      if (visited[i]) continue;
      int now = i;
      vector<int> tmp;
      do {
        tmp.push_back(now);
        visited[now] = 1;
        now = b[now];
      } while(now!=i);
      cycle.push_back(tmp);
    }
    double ans = 0;
    ll sub = 1;
    REP(i, cycle.size()) {
      int start;
      double mi = INF;
      int tmp = 0;
      REP(j, cycle[i].size()) {
        //cout << mi << " " << q[cycle[i][j]] - p[cycle[i][j]] << endl;
        int cc = cycle[i][j];
        if (abs(mi - (1/p[cc] - 1/q[cc])) < EPS) {
          tmp++;
        } else if (mi > 1/p[cc] - 1/q[cc]) {
          mi = 1/p[cc] - 1/q[cc];
          start = j;
          tmp = 1;
        }
      }
      sub = (sub*tmp)%M;
      //cout << "start = " << start << endl;
      REP(j, cycle[i].size()) {
        //cout << cycle[i][j] << " ";
        if (start == j) {
          ans += 1.0/p[cycle[i][j]];
        } else {
          ans += 1.0/q[cycle[i][j]];
        }
      }
    }
    vector<int> v;
    REP(i, cycle.size()) {
      v.push_back(cycle[i].size());
    }
    printf("%.12f %lld\n", ans, (sub*func(v)) % M);
    //cout << ans << " " << (sub*func(v)) % M << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 1964
final_rank: 11

code_snippet: #include <string> 
#include <algorithm> 
#include <cfloat> 
#include <climits> 
#include <cmath> 
#include <complex> 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <functional> 
#include <iostream> 
#include <map> 
#include <memory> 
#include <queue> 
#include <set> 
#include <sstream> 
#include <stack> 
#include <utility> 
#include <vector> 

#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define ALL(x) (x).begin(),(x).end() 
typedef long long ll;
using namespace std; 
const double eps = 1e-12;

const int MAX_N = 110;
const ll DIV = 100000007;

int n, id[MAX_N];
double p[MAX_N], w[MAX_N];
bool visited[MAX_N];
int comb[MAX_N][MAX_N];

void label(int v, vector<int> &t){
    if(visited[v]) return;
    visited[v] = true;
    t.push_back(v);
    label(id[v], t);
}
void solve(){
    for(int i = 0; i < n; ++i){
        p[i] = 1 / p[i]; w[i] = 1 / w[i];
    }
    double ex = 0.0;
    ll way = 1;
    int m = 0;
    memset(visited, 0, sizeof(visited));
    vector<vector<int> > v;
    for(int i = 0; i < n; ++i){
        if(visited[i]) continue;
        vector<int> tv;
        label(i, tv);
        v.push_back(tv);
        way = (way * comb[m + tv.size()][m]) % DIV;
        m += tv.size();
    }
    EACH(i, v){
        double sum = 0.0;
        double diff = DBL_MAX;
        int cnt = 0;
        EACH(j, *i){
            int idx = *j;
            sum += w[idx];
            if(p[idx] - w[idx] < diff - eps){
                diff = p[idx] - w[idx];
                cnt = 1;
            }
            else if(abs(p[idx] - w[idx] - diff) < eps){
                ++cnt;
            }
        }
        ex += sum + diff;
        way = (way * cnt) % DIV;
    }
    printf("%.11lf %d\n", ex, way);
}
int init(){
    memset(comb, 0, sizeof(comb));
    for(int i = 0; i < MAX_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]) % DIV;
    }
}
int main(){
    init();
    while(scanf("%d", &n), n){
        for(int i = 0; i < n; ++i){
            scanf("%lf%d%lf", &p[i], &id[i], &w[i]);
        }
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<queue>
#include<cstdio>
#include<climits>
#include<cmath>
#include<cstring>
#include<string>
#include<sstream>
#include<numeric>
#include<cassert>

#define f first
#define s second
#define mp make_pair

#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define rep(i,s,n) for(int i=(s); i<(int)(n); i++)
#define FOR(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define ALL(c) (c).begin(), (c).end()
#define IN(x,s,g) ((x) >= (s) && (x) < (g))
#define ISIN(x,y,w,h) (IN((x),0,(w)) && IN((y),0,(h)))
#define print(x) printf("%d\n",x)

using namespace std;

typedef unsigned int uint;
typedef long long ll;

const int _dx[] = {0,1,0,-1};
const int _dy[] = {-1,0,1,0};

int getInt(){
  int ret = 0,c;
  c = getchar();
  while(!isdigit(c)) c = getchar();
  while(isdigit(c)){
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

int id[100];
long double p[100];
long double w[100];
bool flag[100];
int cmb[101][101];

long double kitai(long double prob){
  if(prob == 1.0) return 1.0;
  return 1.0 / prob;
}

int main(){
  int n;

  REP(i, 101){
    cmb[i][0] = cmb[i][i] = 1;
    for(int j = 1; j < i; j++)
      cmb[i][j] = (cmb[i-1][j-1] + cmb[i-1][j]) % 100000007;
  }

  while(scanf("%d", &n), n){
    int cnt = 1;
    int sum = 0;
    long double ans = 0.0;

    REP(i,n) cin >> p[i] >> id[i] >> w[i];
    REP(i,n) flag[i] = false;
    REP(i,n) if(!flag[i]){
      int ii = i;
      int c  = 0;

      long double maxp = 0.0;
      int pcnt    = 0;

      while(!flag[ii]){
        long double tmp = 0.0;
        for(int now = ii; ; now = id[now]){
          if(id[now] == ii){
            tmp += kitai(p[now]);
            break;
          }else{
            tmp += kitai(w[now]);
          }
        }
#define ABS(x) ((x) < 0 ? -(x) : (x))
        if(maxp == 0.0 || maxp - 1e-11 > tmp){
          maxp = tmp;
          pcnt = 1;
        }else if(ABS(maxp - tmp) < 1e-11){
          pcnt++;
        }

        flag[ii] = true;
        ii = id[ii];
        c++;
      }
      cnt = (cnt * (long long)cmb[sum + c][c]) % 100000007;
      cnt = (cnt * (long long)pcnt) % 100000007;
      sum = sum + c;
      ans += maxp;
    }
    printf("%.11f %d\n", (double)ans, cnt);
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1060
final_rank: 8

code_snippet: #include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

typedef long long ll;

const ll M=100000007;
const double EPS=1e-9;

ll xgcd(ll a,ll b,ll &x,ll &y){
	if(b==0){ x=1; y=0; return a; }
	ll g=xgcd(b,a%b,y,x); y-=a/b*x;
	return g;
}

ll modinv(ll a,ll m){
	ll x,y;
	if(xgcd(a,m,x,y)==1) return (x+m)%m;
	return -1;
}

int n,id[100];
double p[100],w[100];

bool vis[100];

void dfs1(int u,vector<int> &cyc){
	if(vis[u]) return;
	vis[u]=true;
	cyc.push_back(u);
	dfs1(id[u],cyc);
}

double dfs2(int u,bool first){
	if(vis[u]) return 0;
	vis[u]=true;
	return 1/(first?p[u]:w[u])+dfs2(id[u],false);
}

int main(){
	ll fact[101]={1},factinv[101]={1};
	rep(i,100){
		fact[i+1]=(i+1)*fact[i]%M;
		factinv[i+1]=modinv(i+1,M)*factinv[i]%M;
	}

	for(;scanf("%d",&n),n;){
		rep(u,n) scanf("%lf%d%lf",p+u,id+u,w+u);

		int m=0;
		vector<int> cyc[100];
		fill(vis,vis+n,false);
		rep(u,n) if(!vis[u]) dfs1(u,cyc[m++]);

		double ans=0;
		ll ans2=fact[n];
		rep(i,m){
			double ex=1e70;
			ll cnt=0;
			rep(j,cyc[i].size()){
				fill(vis,vis+n,false);
				double tmp=dfs2(cyc[i][j],true);
				if(tmp<ex-EPS){
					ex=tmp;
					cnt=1;
				}
				else if(abs(ex-tmp)<EPS){
					cnt++;
				}
			}
			ans+=ex;
			ans2=ans2*cnt%M;
			ans2=ans2*factinv[cyc[i].size()]%M;
		}
		printf("%.11f %ld\n",ans,ans2);
	}

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <complex>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <iterator>
#include <functional>
#include <utility>
#include <algorithm>
#include <numeric>
#include <typeinfo>

using namespace std;

#define dump(n) cerr<<"# "<<#n<<"="<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,n) repi(i,0,n)
#define iter(c) __typeof((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();++i)
#define allof(c) (c).begin(),(c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int,int> pii;

const int MOD=100000007;

int memo[200][200];
int combi(int n,int r)
{
	if(memo[n][r]!=-1) return memo[n][r];
	if(r==0 || r==n) return memo[n][r]=1;
	else return memo[n][r]=(combi(n-1,r-1)+combi(n-1,r))%MOD;
}

void solve(vd& ps,vi& ids,vd& ws)
{
	int n=ps.size();
	vi flg(n);
	vvi loops;
	rep(i,n){
		if(flg[i]) continue;
		flg[i]=1;
		loops.push_back(vi(1,i));
		for(int j=ids[i];j!=i;j=ids[j]){
			flg[j]=1;
			loops.back().push_back(j);
		}
	}
	
	vd es(loops.size(),INT_MAX);
	vi cands(loops.size());
	rep(i,loops.size()){
		double temp=0;
		rep(j,loops[i].size())
			temp+=1.0/ws[loops[i][j]];
		vd diffs(loops[i].size());
		rep(j,loops[i].size())
			diffs[j]=-1/ws[loops[i][j]]+1/ps[loops[i][j]];
		rep(j,loops[i].size())
			es[i]=min(es[i],temp+diffs[j]);
		
		sort(allof(diffs));
		rep(j,diffs.size())
			cands[i]+=abs(diffs[j]-diffs[0])<1e-10;
	}
	
	double rese=accumulate(allof(es),0.0);
	int resp=1;
	for(int i=n,j=0;j<loops.size();i-=loops[j].size(),j++)
		resp=((ll)resp*combi(i,loops[j].size())*cands[j])%MOD;
	printf("%.10f %d\n",rese,resp);
}

int main()
{
	memset(memo,-1,sizeof(memo));
	
	for(int n;cin>>n,n;){
		vi ids(n);
		vd ps(n),ws(n);
		rep(i,n)
			cin>>ps[i]>>ids[i]>>ws[i];
		solve(ps,ids,ws);
	}
	
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1148
final_rank: 9

code_snippet: #include<cstdio>
#include<cmath>
#include<vector>
using namespace std;

int main(){
  int n;
  int id[100];
  double p[100],w[100];
  bool use[100];
  long long int pas[101][101];
  
  for(int i=0;i<=100;i++){
    pas[i][0] = 1;
    pas[0][i] = 1;
  }

  for(int i=1;i<=100;i++){
    for(int j=1;j<=100;j++)pas[i][j] = (pas[i-1][j] + pas[i][j-1]) % 100000007;
  }
  
  for(;;){
    scanf("%d",&n);
    if(!n)break;

    for(int i=0;i<n;i++){
      scanf("%lf %d %lf",&p[i],&id[i],&w[i]);
      use[i] = false;
    }

    double ans = 0.0;
    int rem = n;
    long long int t = 1;
    for(int i=0;i<n;i++){
      if(!use[i]){
	use[i] = true;
	int tmp = i;
	vector<int> l;

	l.push_back(tmp);
	for(;;){
	  tmp = id[tmp];
	  if(tmp==i)break;
	  use[tmp] = true;
	  l.push_back(tmp);
	}

	int num = 1;
	double m = 1.0/p[l[0]] - 1.0/w[l[0]];
	ans += 1.0/w[l[0]];
	for(int j=1;j<(int)l.size();j++){
	  ans += 1.0/w[l[j]];
	  double tmp = 1.0/p[l[j]] - 1.0/w[l[j]];
	  if(abs(m-tmp)<1e-10){
	    num++;
	  }else if(m > tmp){
	    m = tmp;
	    num = 1;
	  }
	}
	ans += m;
	t = (t * num) % 100000007;
	rem -= l.size();
	t = (t * pas[rem][(int)l.size()]) % 100000007;
      }
    }
    printf("%.11lf %lld\n",ans,t);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

int main(){
  int n;
  int id[100];
  double p[100],w[100];
  bool use[100];
  long long int pascal[101][101];

  for(int i=0;i<=100;i++){
    pascal[i][0] = 1;
    pascal[0][i] = 1;
  }

  for(int i=1;i<=100;i++){
    for(int j=1;j<=100;j++)pascal[i][j] = (pascal[i-1][j] + pascal[i][j-1]) % 100000007;
  }
  
  for(;;){
    scanf("%d",&n);
    if(!n)break;

    for(int i=0;i<n;i++){
      scanf("%lf %d %lf",&p[i],&id[i],&w[i]);
      use[i] = false;
    }

    double ans = 0.0;
    int rem = n;
    long long int pattern = 1;
    for(int i=0;i<n;i++){
      if(!use[i]){
	use[i] = true;
	int tmp = i;
	vector<int> loop;

	loop.push_back(tmp);
	for(;;){
	  tmp = id[tmp];
	  if(tmp==i)break;
	  use[tmp] = true;
	  loop.push_back(tmp);
	}

	int num = 1;
	double m = 1.0/p[loop[0]] - 1.0/w[loop[0]];
	ans += 1.0/w[loop[0]];
	for(int j=1;j<(int)loop.size();j++){
	  ans += 1.0/w[loop[j]];
	  if(abs(m-1.0/p[loop[j]] + 1.0/w[loop[j]])<1e-10){
	    num++;
	  }else if(m > 1.0/p[loop[j]] - 1.0/w[loop[j]]){
	    m = 1.0/p[loop[j]] - 1.0/w[loop[j]];
	    num = 1;
	  }
	}
	ans += m;
	pattern = (pattern * num) % 100000007;
	//cout << rem << " " << loop.size() << " " << pascal[rem-(int)loop.size()][loop.size()] << endl;
	rem -= loop.size();
	pattern = (pattern * pascal[rem][(int)loop.size()]) % 100000007;
      }
    }
    printf("%.11lf %lld\n",ans,pattern);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cmath>
#include <map>
using namespace std;

typedef long long lli;
const int MAX_N = 101;
const int M = 100000007;
const double eps = 1e-9;
int N;
double P[MAX_N], W[MAX_N];
int G[MAX_N];
bool vis[MAX_N];
vector<vector<int> > Grp;
int comb[101][101];

bool equals(double a, double b) {
  return fabs(a-b) < eps;
}

void dfs(int p, vector<int> &v) {
  v.push_back(p);
  vis[p] = true;
  if(vis[G[p]]) return;
  dfs(G[p],v);
}

void makeComb() {
  comb[0][0] = 1;
  for(int i = 1; i <= 100; ++i) {
    comb[i][0] = 1;
    for(int j = 1; j < i; ++j) {
      comb[i][j] = (comb[i-1][j-1] + comb[i-1][j])%M;
    }
    comb[i][i] = 1;
  }
}

void make() {
  fill(vis, vis+N, false);
  Grp.clear();
  for(int i = 0; i < N; ++i) {
    if(vis[i]) continue;
    vector<int> v;
    dfs(i, v);
    Grp.push_back(v);
  }
}

pair<double, int> calc(int g) {
  vector<int> &v = Grp[g];
  double minCost = -1;
  int cnt = 0;
  for(int i = 0; i < v.size(); ++i) {
    double cost = 1.0/P[v[i]];
    int p = G[v[i]];
    while(p != v[i]) {
      cost += 1.0/W[p];
      p = G[p];
    }
    if(equals(minCost, cost)) {
      ++cnt;
    } else if(minCost == -1 || cost < minCost) {
      cnt = 1;
      minCost = cost;
    }
  }
  return make_pair(minCost, cnt);
}

void solve() {
  make();
  int c = 1;
  int u = N;
  for(int i = 0; i < Grp.size(); ++i) {
    c = (lli)c*comb[u][Grp[i].size()]%M;
    u -= Grp[i].size();
  }
  double time = 0;
  for(int i = 0; i < Grp.size(); ++i) {
    pair<double, int> p = calc(i);
    time += p.first;
    c = (lli)c*p.second%M;
  }
  printf("%.12f %d\n", time, c);
}

int main() {
  makeComb();
  while(cin >> N && N) {
    for(int i = 0; i < N; ++i) {
      int p;
      cin >> P[i] >> p >> W[i];
      G[p] = i;
    }
    solve();
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1028
final_rank: 7

code_snippet: #include <stdio.h>
#include <iostream>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>

using namespace std;

#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) (EQ((a).real(),(b).real()) && EQ((a).imag(),(b).imag()))

typedef complex<double> P;
typedef long long ll;

const double INF=10000000000.0;
// »ê¼êÌm[hÔÉJÚÅ«éGbWª é©Ç¤©
double p[101][101],w[101][101];
bool passed[101];
vector<int> d[101];

int thisNode;
int cnt;
double minCost=INF;

const ll MOD=100000007;

ll dp[101][101];
ll cmb(int a,int b){
    if(dp[a][b]!=INF)
        return dp[a][b];
    if(a==b)
        return 1;
    if(b==1)
        return dp[a][b]=a;
    return dp[a][b]=((cmb(a-1,b)+cmb(a-1,b-1))%MOD);
}

// AÈOtðì¬µA»ÌOtÅÇÌ|µûªàÁÆàø¦ªÇ¢©ðvZ·é
void dfs(int s,bool start,vector<pair<double,double> > costs){
    // êüµÄ«½çAvZ
    if(passed[s]){
        thisNode=costs.size();
        // Ç±ÌêðÅÉÆé©Åêí¯
        double sum=0;
        for(int i = 0; i < costs.size(); i++)
            sum+=costs[i].second;
        for(int i = 0; i < costs.size(); i++){
            // ÅÌêðè
            double ss=sum-costs[i].second+costs[i].first;
            // ±ÌRXgªÅ¬RXgðXVÅ«é©Ç¤©
            if(!EQ(minCost,ss)&&minCost>ss){
                minCost=ss;
                cnt=1;
            }
            else if(EQ(minCost,ss))
                cnt++;
        }
        return;
    }
    passed[s]=true;
    for(int i = 0; i < d[s].size(); i++){
        int to=d[s][i];
        costs.push_back(make_pair(p[s][to],w[s][to]));
        dfs(to,false,costs);
    }
}

void solve(){

    int n;
    for(int i=0;i<101;i++)
        for(int j=0;j<101;j++)
            dp[i][j]=INF;
  //  ll tmp=(ll)(cmb(100,50)+EPS)%MOD;

    while(cin>>n&&n!=0){
        for(int i = 0; i < 101; i++){
            d[i].clear();
            for(int j = 0; j < 101; j++)
                p[i][j]=w[i][j]=INF;
        }

        for(int i = 0; i < n; i++){
            double pp,ww;
            int id;
            cin>>pp>>id>>ww;
            p[id][i]=1.0/pp;w[id][i]=1.0/ww;
            // ¹ðÇÁ
            d[id].push_back(i);
        }
        // OtðAÈàÌ²ÆÉµ¤
        // »ê¼êªÉÎµÄàÁÆàúÒlÌ¬³¢|µûðvZ·é
        // àµ¯¶lðÂàÌª êÎAL¯µÄ¨­
        memset(passed,0,sizeof(passed));
        int leftNode=n;
        ll mul=1;
        double SumOfminCost=0;
        for(int i = 0; i < n; i++){
            cnt=0;
            if(passed[i])
                continue;
            minCost=INF;
            thisNode=0;
            dfs(i,true,vector<pair<double,double> >());
            // cntÉÅRXgÌæèûªAüÁÄ¢éÌÅA»êà©¯é
            ll tmp=cmb(leftNode,thisNode);
            leftNode-=thisNode;
            mul*=cnt*tmp;
            mul%=MOD;
            SumOfminCost+=minCost;
        }
        mul%=MOD;
        //cout<<SumOfminCost<<" "<<mul<<endl;
        printf("%.10f %d\n",SumOfminCost,(int)mul);
    }
}
int main(){

    solve();

    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 1360
final_rank: 10