[Bzoj5483] [Usaco2018 Dec] Balance Beam_ probability desired convex hull _

bzoj5483 Usaco2018Dec Balance Beam

Topic links : https://lydsy.com/JudgeOnline/problem.php?id=5483

Data range : Slightly.


Problem solution :

First there is a model, is the length of a line segment $ $ L, $ $ F_i each point indicates that there is $ \ frac {1} {2} chance left $, $ \ frac {1} {2} $ chance of To the right. Come endpoint will fall, then went to the probability of the right point.

We found: $ f_i = \ frac {f_ {i-1} + f_ {i + 1}} {2} $, is an arithmetic sequence.

Then, $ f_0 = 0, f_L = 1 $, so $ f_i = \ frac {Li} {L} $.

We then for each point $ i $, setting a stopping point on the left side to the right to set a stopping point, then you can find the answers according to the model.

Stopping point is the point $ (j, a_j) $ into the plane of the convex hull, and on the convex $ I $ packet corresponds to two endpoints of the line segment.

Code :

#include <bits/stdc++.h>

#define N 100010 

using namespace std;

typedef long long ll;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
	int x = 0;
	char c = nc();
	while (c < 48) {
		c = nc();
	}
	while (c > 47) {
		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
	}
	return x;
}

ll a[N], st[N], l[N], r[N], top;

int main() {
	int n = rd();
	for (int i = 1; i <= n; i ++ ) {
		a[i] = rd();
	}
	st[ ++ top] = 0, st[ ++ top] = 1;
	for (int i = 2; i <= n + 1; i ++ ) {
		// st[top - 1], st[top], i
		// \frac{a[st[top]] - a[st[top - 1]]}{st[top] - st[top - 1]} < \frac{a[i] - a[st[top]]}{i - st[top]}
		// \Rightleftarrow (a[st[top]] - a[st[top - 1]]) * (i - st[top]) < (a[i] - a[st[top]]) * (st[top] - st[top - 1])
		while (top >= 2 && (ll)(a[st[top]] - a[st[top - 1]]) * (i - st[top]) < (ll)(a[i] - a[st[top]]) * (st[top] - st[top - 1])) {
			top -- ;
		}
		st[ ++ top] = i;
	}
	for (int i = 1; i < top; i ++ ) {
		for (int j = st[i] + 1; j < st[i + 1]; j ++ ) {
			l[j] = st[i], r[j] = st[i + 1];
		}
		l[st[i]] = st[i], r[st[i]] = st[i];
	}

	for (int i = 1; i <= n; i ++ ) {
		ll ans = 0;
		if (l[i] == r[i]) {
			ans = (ll)a[i] * 100000;
		}
		else {
			ans = (100000 * ((ll)a[l[i]] * (r[i] - i) + (ll)a[r[i]] * (i - l[i]))) / (r[i] - l[i]);
		}
		printf("%lld\n", ans);
	}
	return 0;
}

 

Guess you like

Origin www.cnblogs.com/ShuraK/p/11773773.html