专栏文章

题解:P10668 BZOJ2720 [Violet 5] 列队春游

P10668题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@minn4d0u
此快照首次捕获于
2025/12/02 05:07
3 个月前
此快照最后确认于
2025/12/02 05:07
3 个月前
查看原文

[列队春游] 题解

题意

给定整数序列 aa,对于随机排列 pp,求 fi\sum f_i 的期望。
对于位置 iifif_i 定义为最小的 xx,满足对于任意位置 j,1xjij,1 \leq x \leq j \leq i,均有 apjapia_{p_j} \leq a_{p_i}
数据范围:ai,n107a_i, n \leq 10^7

题解

xi+1x_i + 1 为第 ii 位的贡献,我们要求的是 E(xi+1)\sum \mathbb{E}(x_i + 1)
这等价于求: xi=j<i[ajai 并且 j 到 i 之间的数都小于等于 ai]x_i = \sum_{j<i} [a_j \leq a_i \text{ 并且 } j \text{ 到 } i \text{ 之间的数都小于等于 } a_i]
枚举小于 aia_i 的数,则: xi=k<aiPkx_i = \sum_{k<a_i} P_k 其中 PkP_k 表示数 kkii 产生贡献的概率。
通过古典概型的方法求出 PkP_k。假设有 ss 个小于 aia_i 的数,将 kkaia_i 绑在一起,先不考虑其他的 s1s-1 个小于 aia_i 的数,有 (ns)!(n-s)! 种排列,然后再将剩下 (s1)(s-1) 个数插进来。故概率为:
(ns)!Ans1n!=1ns+1\frac{(n-s)! A_n^{s-1}}{n!} = \frac{1}{n-s+1}
因此: xi=sns+1x_i = \frac{s}{n-s+1}
对于每个数分别求出 xix_i 即可。

算法步骤

  1. 读入 nn 和数组 aa
  2. aa 排序,得到每个 aia_i 的排名,从而得到 sis_i(严格小于 aia_i 的数的个数)
  3. 计算 i=1n(1+sinsi+1)\sum_{i=1}^n \left(1 + \frac{s_i}{n-s_i+1}\right)
  4. 输出结果

复杂度分析

  • 时间复杂度:O(nlogn)O(n \log n)
  • 空间复杂度:O(n)O(n)

代码实现要点

  • 注意处理重复元素的情况
  • 使用双精度浮点数计算期望值并且输出时保留两位小数

CODE

CPP
#include<bits/stdc++.h>
using namespace std;
int n,h[305];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>h[i];
	sort(h+1,h+1+n);
	long double ans=0,pre=0;
	for(int i=1;i<=n;i++){
		if(h[i]!=h[i-1])
			pre=i-1;
		ans+=pre/(n-pre+1);
		ans++;
	}
	cout<<fixed<<setprecision(2)<<ans;
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...