utsubo’s blog

競技プログラミングとか.

100問マラソン 3問目 SRM 664 Div2 Hard: BearSortsDiv2

問題

配列に対しマージソートを適用する.
しかし,そのマージソートは大小比較部分が間違いがあり,数字の大小関係なしに,確率で大小を判定する.
seqという配列が入力として渡されるので,先のマージソートを適用した時,その配列が1,2,...,Nとなるような確率を求め,対数を取って答えよ

制約

1 <= N <= 40

解法

大小比較するごとに50%を選ばないといけないので,大小比較関数が呼び出されるごとに0.5ずつ掛けてlogを取った.

class BearSortsDiv2 {

	public:

	vector<vector<int> > ls;
	double ret;
	bool LESS(int a,int b){
		ret *= 0.5;
		if(ls[a][b] == 1){
			return true;
		}
		else return false;
	}
	double mergeSort(int left,int right,vector<int>& T){
		if(left+1 >= right)return 0;
		int mid = (left+right) / 2;
		mergeSort(left,mid,T);
		mergeSort(mid,right,T);

		int p1 = left,p2 = mid;
		vector<int> merged;
		while(p1 < mid or p2 < right){
			if(p1 == mid){
				merged.push_back(T[p2]);
				p2 += 1;
			}else if(p2 == right){
				merged.push_back(T[p1]);
				p1 += 1;
			}else{
				if(LESS(T[p1],T[p2])){
					merged.push_back(T[p1]);
					p1 += 1;
				}else{
					merged.push_back(T[p2]);
					p2 += 1;
				}
			}
		}
		for(int i=left;i<right;i++){
			T[i] = merged[i-left];
		}
	}

	double getProbability(vector<int> seq) {
		ls.resize(seq.size()+1);
		for(int i=0;i<=seq.size();i++)ls[i].resize(seq.size()+1);

		for(int i=0;i<seq.size();i++){
			for(int j=i+1;j<seq.size();j++){
				ls[seq[i]][seq[j]] = 1;
			}
		}

		ret = 1;
		vector<int> T(seq.size());
		for(int i=0;i<seq.size();i++)
			T[i] = i + 1;

		mergeSort(0,seq.size(),T);

		return log(ret);
	}
};

system test通しておらず.