SRM 664 Div2 Hard BearSortDiv2
TopCoder Statistics - Problem Statement
- editorial を見て解いた。
- 問題見た時 DP とかかな?と思いきやそんなことはなかった。
- mergeSort なんでソート済みの部分列の段階で最終結果と前後が変わっていてはダメ。
class BearSortsDiv2 { public: vector<int> whereIs; int count; bool less(int a, int b) { ++count; // 最終的な結果と一致するように 0.5 の確率で // 適切な比較ができていると考える return whereIs[a] < whereIs[b]; } void mergeSort(int left, int right, vector<int> &T) { if (left+1>=right) return; int mid = (left+right)/2; mergeSort(left,mid,T); mergeSort(mid,right,T); // この段階で T[left...mid], T[mid...right] の順番は // 最終結果の seq の順と矛盾しない。 // この後の sort は T[left...mid] ~ T[mid...right] 間のものだけ int p1 = left; int p2 = mid; vector<int> merged; while (p1 < mid || p2 < right) { if (p1 == mid) { merged.push_back(T[p2]); ++p2; } else if (p2 == right) { merged.push_back(T[p1]); ++p1; } else { if (less(T[p1], T[p2])) { merged.push_back(T[p1]); ++p1; } else { merged.push_back(T[p2]); ++p2; } } } for (int i = left; i < right; ++i) T[i] = merged[i-left]; } double getProbability(vector <int> seq) { int N = seq.size(); whereIs.resize(N+1); count = 0; // // mergeSort の特徴として mregeSort 済みの部分列の再ソートはないので // 最終的な結果 seq になるには各 less の段階で適切な比較ができてなければならない。 // // よって適切な比較ができたときの merge ソートの比較回数 k にたいして // 0.5^k が最終的なソート結果となる確率 // vector<int> T(N); REP(i,N) { T[i] = i+1; whereIs[seq[i]] = i; // 適切な比較をするための逆参照用 } mergeSort(0,N,T); // 0.5^k return log(0.5)*count; } };