[Ybt gold medal navigation 1-1-7] [luogu P6089] book selection question / If you are the one

Book selection question / If you are the one

Topic link: ybt gold medal navigation 1-1-7 / luogu P6089

Topic

There are two kinds of points, the first kind of point will be connected with some second kind of points, and then for each connected second kind of point, this first kind of point will have the probability of choosing this point, otherwise it will jump Go to the next point connected to it. Then if you don’t choose the last one, skip to the first one to continue.
Ask you the probability of expecting reversed pairs.

Ideas

Let’s look at the first point with kkk points of the second kind.

Then let’s look at selecting the iiThe probability of i second point.
Since there are infinite and very troublesome, we only look at the first point.

Its probability of being selected in the first round is ppp , the second round is(1 − p) kp (1-p)^kp(1p)k p, the third round is(1 − p) 2 kp (1-p)^{2k}p(1p)2 k p, and so on.
We can find that the total probability is∑ i = 0 ∞ (1 − p) ikp \sum\limits_{i=0)^{\infty }(1-p)^{ik)pi=0(1p)i k p.
Then we see how to simplify, we can find that it is a sum of geometric series.

Then we are equal to a 1 (1 − qn) 1 − q \dfrac{a_1(1-q^n)}{1-q}1qa1(1qn), The formula can be changed to this:
p (1 − (1 − p) k × ∞) 1 − (1 − p) k \dfrac{p(1-(1-p)^{k\times\infty} )}{1-(1-p)^k}1(1p)kp(1(1p)k×), Which is p (1 − (1 − p) ∞) 1 − (1 − p) k \dfrac{p(1-(1-p)^{\infty})){1-(1-p)^k }1(1p)kp(1(1p))

Because 1 − p 1-p1p is a number greater than zero and less than one, so its infinite power is infinitely close to zero, and then one minus it is infinitely close to one.
Then this formula becomes this:p 1 − (1 − p) k \dfrac{p}{1-(1-p)^k}1(1p)kp

Then we get the probability of the first point being selected, then how to find the probability of the second and third points?
Obviously, we can know that the probability of these points being selected is the probability of the previous point being selected × (1 − p) \times (1-p)×(1p ) . (That is, the last one is not selected, and then this one will not be selected one more time, just multiply one more time× (1 − p) \times (1-p)×(1p)

No. iiThe probability of i being selected isp × (1 − p) i − 1 1 − (1 − p) k \dfrac{p\times(1-p)^{i-1}){1-(1- p)^k}1(1p)kp×(1p)i1

Obviously, fast exponentiation is used to find the power, then we can find the probability.

Next, let's look at what to expect.

Seeing that the title requires inverted pairs, we will naturally think of a tree array of inverted pairs.
But what it wants is expectations.
The ordinary reverse order is to add one each time, then we add the probability of this point. And when looking for the previous reverse order pair, the probability of this point being selected must be multiplied.
In this way, we can get the probability that these two points are selected multiplied, which is the expectation of this reverse pair.

Then one thing to pay attention to is that the problem will get stuck in accuracy and use long double to solve it.

Code

#include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

int n, m, x, y, size;
vector <int> a[500001];
long double p, re, ans, tree[500001], thi;

void build(int x, long double y) {
    
    //树状数组
	for (int now = x; now <= 500000; now += now & (-now))
		tree[now] += y; 
}

long double ask(int x) {
    
    
	re = 0;
	for (int now = x; now; now -= now & (-now))
		re = re + tree[now];
	return re;
}

long double ksm(long double x, int y) {
    
    //快速幂
	re = 1.0;
	while (y) {
    
    
		if (y & 1) re = re * x;
		x = x * x;
		y >>= 1;
	}
	return re;
}

int main() {
    
    
	scanf("%d %d", &n, &m);
	scanf("%Lf", &p);
	
	for (int i = 1; i <= m; i++) {
    
    
		scanf("%d %d", &x, &y);
		a[x].push_back(y);
	}
	
	for (int i = 1; i <= n; i++)
		sort(a[i].begin(), a[i].end());
	
	ans = 0.0;
	for (int i = 1; i <= n; i++) {
    
    
		size = a[i].size();
		for (int j = 0; j < size; j++) {
    
    
			thi = p * ksm(1.0 - p, j) / (1.0 - ksm(1.0 - p, size));//算出来的概率
			ans += (ask(m) - ask(a[i][j])) * thi;
			build(a[i][j], thi);
		}
	}
	
	printf("%.2Lf", ans);
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/112497210