Problem Statement |
|
Bear Limak is chilling in the forest then he suddenly found a computer program. The program was a correct implementation of mergesort. Below can find the program in pseudocode.
# mergesort (left,right) Sorts elements left, left+1, ..., right-1 of a global array tfunction mergesort (left,right): # If there is on the most one element, we be done if left+1 >= Right:return # Otherwise, split the sequence into Halv Es, sort each half separately mid = (left + right) Div 2 mergesort (left,mid) mergesort (mid,right) # then Merge The halves together merged = [] # an empty sequence P1 = left P2 = Mid while (P1 < mid) or (P2 < right): if p1 = = Mid:merged.append (T[p2]) P2 + = 1 else if P2 = = right: Merged.append (T[p1]) p1 + 1 else: if (Pos[a[p1]] < POS[A[P2]) Tmp.push_back (a[p1++]); &NBSP ; Else Tmp.push_back (a[p2++]); # Finally, move the merged elements back to the original array for I froM left to right-1 inclusive:t[i] = Merged[i-left]
Limak noticed that one part of the implementation is missing:the function less. Can probably guess that the function was supposed to return a Boolean value stating whether the first argument are less than the second argument. However, Limak is a bear and he didn ' t know that. Instead he implemented his own version of the This function. Limak ' s function uses a true random number generator. Each of the possible return values (True, false) are returned with probability percent.
The random values generated in different calls to Limak's function less is mutually independent. Note that even if-twice with the same arguments, and the return values may differ.
After implementing less, the Limak decided to run he brand new program. He initialized the global array T to contain N elements. Then, he filled the values 1 through N into the array:for each valid I, he set t[i] to i+1. Finally, he executed the function mergesort (0,n).
Even with Limak's new less function, the program never crashes. On the other hand, it does isn't necessarily produce a sorted sequence when it terminates. In general, when the program terminates, the array T would contain some permutation of the numbers 1 through N.
After running the program many times, Limak have noticed that different output permutations is produced with different pro Babilities. Your task is to help him learn more about these probabilities. More precisely, your task was to compute the probability, a given sequence would appear as the output of Limak ' s program .
You is given a vector <int> sortedsequence with N elements, containing a permutation of 1 through N. Let P is the probability that Limak's program, when run to an array with N elements, outputs this permutation. Return the value log (P), where log denotes the natural (base e) logarithm. |
Definition |
|
Class: |
BearSortsDiv2 |
Method: |
Getprobability |
Parameters: |
Vector <int> |
Returns: |
Double |
Method Signature: |
Double getprobability (vector <int> seq) |
(Be sure your method was public) |
|
Limits |
|
Time limit (s): |
2.000 |
Memory Limit (MB): |
256 |
Stack Limit (MB): |
256 |
|
Notes |
- |
Your return value must has absolute or relative error smaller than 1e-9. |
- |
You may assume this for each N and for each permutation p of 1 through N the probability that p appears as the output of L Imak ' s program is strictly positive. |
Constraints |
- |
sortedsequence would contain exactly N elements. |
- |
N would be between 1 and inclusive. |
- |
Elements of Sortedsequence would be between 1 and N, inclusive. |
- |
Elements of sortedsequence would be pairwise distinct. |
Main topic:
In the merge sort process, the "merge" step is:
if (isless (A[P1]],A[P2))) Tmp.push_back (a[p1++]);
else Tmp.push_back (a[p2++]);
The probability of isless () function returns True or FALSE.
What is the probability of the final merge to get a given sequence number?
(Output log (probability))
Ideas:
Merging is the determination of the order of two numbers, given the number of known sequences, obviously there is only one way to merge
So we can calculate the probability by simulating the merge sort again.
#pragma COMMENT (linker, "/stack:1024000000,1024000000") #include <iostream> #include <cstring> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include < string> #include <vector> #include <cstdio> #include <ctime> #include <bitset> #include < Algorithm> #define SZ (x) ((int) (x). Size ()) #define ALL (v) (v). Begin (), (v). End () #define A foreach (I, v) for (__typeof (v ). Begin ()) I = (v). Begin (); I! = (v). End (); + + i) #define REP (i,n) for (int i=1; i<=int (n); i++) using namespace std;typedef long long ll; #define X First#define Y Secondtypedef pair<int,int> pii;const int N = 1e3+100;int pos[n];vector<int>tmp;int A[N];d ouble ans = 0;void M Erge (int l,int r) {if (l+1 >= R) return; int m = (l+r) >>1; Merge (l,m), merge (M,r); int p1 = l, p2 = m; while (P1 < m | | P2 < r) {if (P1 = = m) tmp.push_back (a[p2++]); else if (P2 = = r) tmp.push_back (a[p1++]); else{ans + = log (0.5),//log (a*b) = Loga + LOGB if (Pos[a[p1]] < POS[A[P2]] ) Tmp.push_back (a[p1++]); else Tmp.push_back (a[p2++]); }} foreach (It,tmp) a[l++] = *it; Tmp.clear ();} Class BearSortsDiv2 {public:double getprobability (vector <int> seq) {int top = 0; Ans = 0; foreach (It,seq) {a[top] = top+1; Pos[*it] = top++; } Merge (0,sz (seq)); return ans; }};
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
SRM 664 Div2 hard:bearsortsdiv2 (merge sort)