zoukankan      html  css  js  c++  java
  • [bzoj5483][Usaco2018 Dec]Balance Beam_凸包_概率期望

    bzoj5483 Usaco2018Dec Balance Beam

    题目链接https://lydsy.com/JudgeOnline/problem.php?id=5483

    数据范围:略。


    题解

    首先有一个模型,就是长度为$L$的线段,$f_i$表示这个点每次有$frac{1}{2}$的几率向左,$frac{1}{2}$的几率向右。走到端点会掉下去的话,走到右端点的概率。

    我们发现:$f_i=frac{f_{i-1}+f_{i+1}}{2}$,是一个等差数列。

    然后,$f_0 = 0, f_L=1$,所以$f_i=frac{L-i}{L}$。

    接着,我们对于每个点$i$,设置一个左侧停止点设置一个右侧停止点的话,就可以根据模型求出答案。

    停止点,就是把点$(j,a_j)$放进平面的上凸包,然后$i$在凸包上对应的线段的两个端点即可。

    代码

    #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
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    C语言归并排序
    三重for循环实现对二维数组的按列排序(JavaScript)
    MySQL创建子视图并查看的时候,字符集报错问题
    Windows下配置lua环境
    《机器学习》周志华西瓜书读书笔记
    《消费金融真经》读书笔记
    北海之行-小纪
    2017中国资产管理行业发展报告——思维导图
    工作小纪
    全球化3.0:世界是红的 (转载)
  • 原文地址:https://www.cnblogs.com/ShuraK/p/11773773.html
Copyright © 2011-2022 走看看