其他分享
首页 > 其他分享> > Luogu P1291 百事世界杯之旅

Luogu P1291 百事世界杯之旅

作者:互联网

题目大意

有 \(n\) 个明星,每个明星有 \(\dfrac 1 n\) 的概率被抽中,求充中 \(n\) 个明星的期望次数。

题解

设 \(E(i)\) 为抽到 \(i\) 个明星的期望次数,则 \(E(i) = E(i-1) + \sum\limits_{k=1}^{\infty}k \times \left(\dfrac{i-1}{n}\right)^{k-1}\times \dfrac{n-i+1}{n}\) 。
显然 \(\dfrac{i-1}{n} \times E(i) = \dfrac{i-1}{n} \times E(i-1) + \sum\limits_{k=1}^{\infty}k \times \left(\dfrac{i-1}{n}\right)^k \times \dfrac{n-i+1}{n}\) 。
两式相减得到 \(E(i) = E(i-1) + \sum\limits_{k=1}^{\infty}\left(\dfrac{i-1}{n}\right)^{k-1} = E(i-1) + \lim\limits_{k \to \infty} 1 \times \dfrac{1 - \left(\tfrac{i-1}{n}\right)^k}{1 - \tfrac{i-1}{n}} = E(i-1) + \dfrac{n}{n-i+1}\) 。
故 \(E(n) = \sum\limits_{i=1}^{n}\dfrac{n}{i}\) 。

#include <cstdio>

long long gcd(long long a, long long b) {
	long long c;
	while (b) {
		c = a % b;
		a = b;
		b = c;
	}
	return a;
}

int n;
struct Frac {
	long long a, b;
	
	Frac(long long _a = 0, long long _b = 1) {
		a = _a;
		b = _b;
	}
	
	Frac operator + (Frac x) {
		Frac res;
		res.a = a * x.b + b * x.a;
		res.b = b * x.b;
		if (res.a) {
			long long g = gcd(res.a, res.b);
			res.a /= g;
			res.b /= g;
		} else {
			res.b = 1;
		}
		return res;	
	}
} E;

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i)
		E = E + (Frac){n, i};
	if (E.b == 1) {
		printf("%lld", E.a);
		return 0;
	}
	long long m = E.a / E.b, t1 = m, t2 = E.b, c1 = 0, c2 = 0;
	E.a %= E.b;
	while (t1) {
		++c1;
		t1 /= 10;
	}
	while (t2) {
		++c2;
		t2 /= 10;
	}
	for (int i = 1; i <= c1; ++i)
		putchar(' ');
	printf("%lld\n%lld", E.a, m);
	for (int i = 1; i <= c2; ++i)
		putchar('-');
	putchar('\n');
	for (int i = 1; i <= c1; ++i)
		putchar(' ');
	printf("%lld", E.b);
	return 0;
}

另一种做法(自己推自己)可以参考这里

标签:dfrac,Frac,limits,Luogu,P1291,long,times,百事,res
来源: https://www.cnblogs.com/kcn999/p/13708162.html