「 客星璀璨之夜 」(stars)

虽然不清楚是不是那两人的力量

在那个风暴肆虐的夜晚,的确有一瞬

真的在那一瞬间,在云破天开的时候

透过空隙中看到的璀璨星空,不知为何倒映眼中不能忘怀

——《奇迹召唤星辰》

【题目描述】

小苗望着星空,在高中学习了几年物理后正式成为一名理科生后,她突然脑洞大开: 将星空简化成一个数轴,数轴上有 2n + 1 个位置,分别为 x_1 , x_2 , … , x_2n+1,其中奇 数位置有一个正物质恒星,偶数位置有一颗反物质行星。在这里,我们不考虑天体之间 力的作用。

小苗将发动奇迹的力量,从剩下的反物质行星中随机选择一颗,并随机选择向左或 向右,然后施加一个初速度。显然,当正物质与反物质相撞后,它们会发生湮灭并同时 消失。

当上一个行星湮灭后,小苗会再次发动奇迹的力量,直到不存在行星。可以注意到, 没有行星会永远运动下去。 小苗除了学习了物理外,还学习了概率论,所以她想知道所有行星在湮灭之前的运 动距离之和的期望为多少。但是这对于周老师实在是太难了,所以小苗决定向你求助。 你只需要算出期望值 mod 998244353 的结果。

p.s.:如果你不知道模意义下的期望怎么求,首先期望一定能写成有理数 a/b,在 mod 998244353 意义下存在唯一正整数 b^−1 满足 b × b^−1 ≡ 1 mod 998244353,你只 需要输出 a × b^−1 mod 998244353 的值即可。

【输入格式】

从文件 stars.in 中读入数据。

第一行包含一个正整数 n。接下来一行共 2n + 1 个整数 x_1 , x_2 , … , x_2n+1 表示所有天 体的坐标。保证 xi 递增给出。

【输出格式】

输出到文件 stars.out 中。

输出期望值 mod 998244353 的结果。

【样例 1 输入】

1

1 2 3

【样例 1 输出】

1

【样例 2 输入】

3

1 2 3 4 5 6 7

【样例 2 输出】

332748122

【样例 2 解释】

共存在 3! × 2^3 = 48 种不同的可能性,限于篇幅不列举所有情况,期望值为 13/3 。

【样例 3 输入】

10

0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210

【样例 3 输出】

969129126

【数据范围与约束】

对于所有测试点,满足 n ≤ 3000, −10^9 ≤ x_1 < x_2 < ⋯ < x_2n+1 ≤ 10^9。

题解

我们把题意转换一下,相当于每次随机把相邻两颗星球(一正一反)并在一起湮灭,消失,旁边的两颗星球变为相邻。

每个行星都会唯一地运动一段距离,显然每个行星都有概率与n+1颗恒星湮灭,也就是每个行星有n+1种情况,n+1种概率,总的就有n(n+1)种情况,可以直接枚举,复杂度为n^2,只要算出当前行星与每一颗恒星湮灭的概率,再分别乘对应的移动距离,加起来就是总期望了。

假如我们要让左数第 i 个行星与左数第 j 颗恒星相撞,这个概率怎么算 ?

j 在左边或在右边肯定是两种情况,但本质是一样的,概率和距离、方向无关。

那么得满足几个条件,

  1. i 朝着 j 的方向合并 (p = 1/2)
  2. i ~ j 之间的所有星球得在 i 之前湮灭掉,并且不影响到 j (p = ?)
  3. i → j 方向更远处的星球不能影响到 j ,但可以不在 i 之前湮灭 (p = ?)

分别考虑一下2和3吧

条件2

下图的黑点是反物质行星,白点是恒星

设内部湮灭的中间点总共有 L 对,那么显然他们内部湮灭的概率只跟 L 大小有关,跟距离、位置、甚至方向都无关,

所以设 dp1[i] 为长度为 2i (即中间有 i 对)的连续一段星球互相湮灭的概率(为了不重复考虑,dp1就只要求自己内部不影响外面,而暂不考虑外面对自己的影响),

再设 dp0[i] 为长度为 2i 的连续一段星球互相湮灭,且最外面两个星球最后相撞的概率,

(乘二分之一是因为最外面的那个行星得朝内,乘 i 分之一是因为最外面那个行星得是 i 个行星中最后移动的)

那么简单想一下会发现如下转移:

简单解释一下为什么那里是dp0而不是dp1,

如果是dp1的话,首先他会算重,然后是需要加上自己,会出问题,

枚举 j 实际上是枚举第一个dp0的长度。

好了,我们继续看上面的三个条件,发现前两个条件可以合并一下,用一个包含 i,j 的 dp0 表示,dp1,dp0都可以 n^2 预处理

条件3

这个就比较麻烦了,可以允许两种情况

第一种情况就直接是dp1[j-1],很简单

第二种情况是笔者做法的重难点,咱们慢慢来

重难点

首先需要强调的是,其中任意一个行星都可以选择在 i 合并之后再出去合并,这样的话,假设该行星为 k

我们发现这个概率居然和 i~k 的总长度有关,而对于每个不同的 k ,i~k 的长度又不一样,那是不是要n^3了呢?

不,绝对不能n^3,

我们发现如果设 dp2[x][y] 为上图 i~j 长度为 2x 、j~k 长度为 2y 时满足 k 最后的概率,那么 dp2 可以 O(1) 转移,

然后预处理一下 dp2[i][1]~dp2[i][j]的前缀和,就可以直接带入了。

本来dp2是要乘那个dp0[i]的,至于转移方程中为什么要打上一个括号,是为了总计算方便,笔者的代码里没有乘它。

复杂度

所有dp都可以预处理,都是n^2,枚举也是n^2的,总复杂度

CODE

#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 6010
#define LL long long
#define DB double
#define ENDL putchar('\n')
//#define int LL
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x = x*10+(s-'0');s = getchar();}
return f * x;
}
const int jzm = 998244353;
int n,m,i,j,s,o,k,a,b;
int fac[MAXN],inv[MAXN],invf[MAXN],pow2[MAXN],inv2[MAXN];
int C(int n,int m) {return fac[n] *1ll* invf[n-m] % jzm *1ll* invf[m] % jzm;}
int ad[MAXN];
int dp[MAXN],dp0[MAXN],dpr[MAXN>>1][MAXN>>1];//dp1,dp0,dp2/dp0[i]
int main() {
freopen("stars.in","r",stdin);
freopen("stars.out","w",stdout);
n = read();
pow2[1] = 2;inv2[0] = 1;inv2[1] = 499122177;
fac[0] = fac[1] = inv[0] = inv[1] = invf[0] = invf[1] = pow2[0] = 1;
for(int i = 2;i <= (n<<1|1) || i <= 10;i ++) {
fac[i] = fac[i-1] *1ll* i % jzm;
inv[i] = (jzm - inv[jzm % i]) *1ll* (jzm / i) % jzm;
invf[i] = invf[i-1] *1ll* inv[i] % jzm;
pow2[i] = pow2[i-1] *2ll % jzm;
inv2[i] = inv2[i-1] *1ll* inv2[1] % jzm;
}
dp0[0] = dp[0] = 1;
for(int i = 1;i <= n;i ++) {
dp0[i] = dp[i-1] *1ll* inv[i] % jzm *1ll* inv2[1] % jzm;
dp[i] = dp0[i];
for(int j = 1;j < i;j ++) {
(dp[i] += dp[j] *1ll* dp0[i-j] % jzm) %= jzm;
}
}
// !!!必须先处理了dp0和dp1才能处理dp2!!!
for(int i = 1;i <= n;i ++) {
for(int j = 1;j+i <= n;j ++) {
dpr[i][j] = dp[j-1] % jzm *1ll* inv2[1] % jzm *1ll* inv[i+j] % jzm;//由于下面计算概率时乘了个dp0[i]的 ,所以这里不用乘dp0[i]
(dpr[i][j] += dpr[i][j-1]) %= jzm;
}
}
// 预处理结束 ,可能处理了一些多余的,不过没关系
for(int i = 1;i <= (n<<1|1);i ++) {
ad[i] = read();
}
// 输入结束
int tot = fac[n] *1ll* pow2[n] % jzm; //方便调试而已,并没用
int ans = 0;
for(int i = 1;i <= n;i ++) {
for(int j = 1;j <= i;j ++) {
int p = dp0[i-j+1] *1ll* ((dp[j-1] + dpr[i-j+1][j-1]) % jzm) % jzm;
(ans += (ad[i<<1] - ad[(j<<1)-1]) % jzm *1ll* p % jzm) %= jzm;
// printf("(%d -> %d) : %d\n",i,j,p);
}
for(int j = i+1;j <= n+1;j ++) {
int p = dp0[j-i] *1ll* ((dp[n+1-j] + dpr[j-i][n+1-j]) % jzm) % jzm;
(ans += (ad[(j<<1)-1] - ad[i<<1]) % jzm *1ll* p % jzm) %= jzm;
// printf("(%d -> %d) : %d\n",i,j,p);
}
}
printf("%d\n",ans);
return 0;
}

HDU6848改编题(弱化)——客星璀璨之夜(stars)的更多相关文章

  1. NOIP 模拟 $28\; \rm 客星璀璨之夜$

    题解 \(by\;zj\varphi\) 概率与期望,考虑 \(\rm dp\) 设 \(dp_{i,j}\) 为消除 \(i-j\) 这一段行星的期望,转移: 枚举 \(k\) 为当前状态下第一个撞 ...

  2. Solution -「LOCAL」客星璀璨之夜

    \(\mathcal{Description}\)   OurOJ.   给定坐标轴上的 \(2n+1\) 个坐标 \(x_1,x_2,\cdots,x_{2n+1}\),其中偶数下标的位置是一个小球 ...

  3. 期望dp好题选做

    前言: 最近连考两场期望dp的题目,sir说十分板子的题目我竟然一点也不会,而且讲过以后也觉得很不可改.于是开个坑. 1.晚测10 T2 大佬(kat) 明明有\(O(mlog)\)的写法,但是\(m ...

  4. (好题)树状数组+离散化+DFS序+离线/莫队 HDOJ 4358 Boring counting

    题目传送门 题意:给你一棵树,树上的每个节点都有树值,给m个查询,问以每个点u为根的子树下有多少种权值恰好出现k次. 分析:首先要对权值离散化,然后要将树形转换为线形,配上图:.然后按照右端点从小到大 ...

  5. [LeetCode] Matchsticks to Square 火柴棍组成正方形

    Remember the story of Little Match Girl? By now, you know exactly what matchsticks the little match ...

  6. PKUSC 模拟赛 day1 上午总结

    思考了一下第二题,觉得有无数种乱搞做法 类似什么bitset压位,MCS染色之类奇怪的做法 然而都是玄学正确性或者玄学复杂度 先放题解把 第一题显然具有单调性,二分就可以啦 O(nlogn),貌似输出 ...

  7. 历年NOIP选题题解汇总

    联赛前上vijos板刷往年联赛题,使用在线编辑编写代码,祝我rp++. 废话不多说,挑比较有意思的记一下. 题目是按照年份排序的,最早只到了03年. 有些题目因为 我还没写/很早之前写的忘了 所以就没 ...

  8. 解题:CF622F The Sum of the k-th Powers

    题面 TJOI2018出CF原题弱化版是不是有点太过分了?对,就是 TJOI2018 教科书般的亵渎 然而我这个问题只会那个题的范围的m^3做法 回忆一下1到n求和是二次的,平方求和公式是三次的,立方 ...

  9. 【Treap 例题】神秘岛(island)

    神秘岛(island) 题目描述: 除了敲代码和撩妹,旅行是cxw123 的第三爱好.他来到了澳大利亚东北部的大宝礁,在这里,有一个隔绝人世的神秘岛,这个岛不同于附近其他的珊瑚岛,它的生长速度极快,甚 ...

随机推荐

  1. SRE,了解一下?35+岁程序员新选择

    摘要:随着云业务的发展,今后会有越来越多的工程师深入到SRE领域. 本文分享自华为云社区<浅谈SRE角色认知>,作者: SRE确定性运维. 一.什么是SRE? SRE(Site Relia ...

  2. Boogie's First Blog

    这是boogie在博客园的第一篇随笔,祝大家身体健康,心情愉悦.

  3. redis主从复制(九)

    先来简单了解下redis中提供的集群策略, 虽然redis有持久化功能能够保障redis服务器宕机也能恢复并且只有少量的数据损失,但是由于所有数据在一台服务器上,如果这台服务器出现硬盘故障,那就算是有 ...

  4. Maven + SSM环境搭建

    Maven + SSM 之前Maven+SSM都是照着搭建的,自己想写点什么的时候发现搭建的过程不清楚. 于是花了时间边整理思路边搭建,并把搭建过程记录下来. 视频看来终觉浅,还是需要自己动手实践,捋 ...

  5. bat实现删除BCUnrar.dll实现无限使用

    删除项目:计算机\HKEY_CURRENT_USER\Software\Scooter Software\Beyond Compare 4下的CacheId 项可以实现Beyond Compare 4 ...

  6. rhel6下eth1恢复eth0

    问题:VMware 虚拟机中,从模板克隆出来的虚拟机的网卡名都会变成为eth1,而程序或者脚本,默认网卡是eth0,这时需要将eth1改为eth0. 原因:/etc/udev/rules.d/70-p ...

  7. POI导出复杂Excel,合并单元格(2)

    /** * 导出excel (HSSFWorkbook) */ @GetMapping("/testExport") public void testExport1(HttpSer ...

  8. css-sticky 定位

    前言 我们大多都了解绝对定位.相对定位.static 和 fixed 定位,而 sticky 定位常常会被忽略,本文来总结一下其相关使用方法. 正文 1.常见使用效果 我们滚动滚动条时,当 " ...

  9. 【Azure Developer】记录一次使用Java Azure Key Vault Secret示例代码生成的Jar包,单独运行出现 no main manifest attribute, in target/demo-1.0-SNAPSHOT.jar 错误消息

    问题描述 创建一个Java Console程序,用于使用Azure Key Vault Secret.在VS Code中能正常Debug,但是通过mvn clean package打包为jar文件后, ...

  10. 阿里云搭建redis集群

    1.安装redis # 下载redis包 wget http://download.redis.io/releases/redis-5.0.5.tar.gz tar -zxvf redis-5.0.5 ...