「 客星璀璨之夜 」(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. 2021.03.20【NOIP提高B组】模拟 总结

    区间 DP 专场:愉快爆炸 T1 题目大意 有 \(n\) 个有颜色的块,连续 \(k\) 个相同颜色的就可以消掉 现在可以在任意位置插入任意颜色的方块,问最少插入多少个可以全部抵消 题解 先把连续的 ...

  2. kafka消费

    消费模型 kafka模型使用了 发布/订阅.点对点模型. 消息发布 在producer端,通过分片策略,找到对应topic下面的Partition leader,把消息发送到当前Partition 消 ...

  3. 开始讨论离散型随机变量吧!《考研概率论学习之我见》 -by zobol

    上一文中,笔者给出了随机变量的基本定义:一个可测映射,从结果空间到实数集,我们的目的是为了引入函数这个数学工具到考研概率论中,但是我们在现实中面对的一些事情结果,映射而成的随机变量和其对应的概率值,并 ...

  4. 关于一次Web线下面试的思考

    前言: 今天面试一家Web前端的公司,由于跟初筛的面试官关系挺好,按理来说我在第一次线上面试就应该被淘汰了(呜呜呜),接下来是线下面试,不出意外的话,我凉了.但是这些天的面试经验并非全无收获.我的线下 ...

  5. ShardingSphere-proxy-5.0.0容量范围分片的实现(五)

    一.修改配置文件config-sharding.yaml,并重启服务 # # Licensed to the Apache Software Foundation (ASF) under one or ...

  6. 监听 Markdown 文件并热更新 Next.js 页面

    Next.js 提供了 Fast-Refresh 能力,它可以为您对 React 组件所做的编辑提供即时反馈. 但是,当你通过 Markdown 文件提供网站内容时,由于 Markdown 不是 Re ...

  7. 令你瞠目结舌的 Python 代码技巧

    0. for-else 在 Python 中,else 不仅可以与 if 搭配使用,还可以与 for 结合. python答疑 咨询 学习交流群2:660193417### for x in rang ...

  8. windows系统下.NET CORE c# 通过bat脚本发布iis应用程序,半智能点击式ci/cd

    这里以git为例子讲解: 第一个 pullCode.bat 文件是 拉取代码 git pull 第二个 publish.bat 脚本,编译代码,并发布指定文件夹 dotnet publish &quo ...

  9. 11.2 Android Studio如何切换主题和更改字体

    如何进入设置? 全平台启动界面 Configure-Preferences 主界面 Windows版本:File-Settings Mac版本:Android Studio-Preferences 外 ...

  10. 【python基础】第19回 多层,有参装饰器 递归 二分法

    本章内容概要 1. 多层装饰器 2. 有参装饰器 3. 递归函数 4. 算法(二分法) 本章内容详解 1. 多层装饰器 1.1 什么是多层装饰器 多层装饰器是从下往上依次执行,需要注意的是,被装饰的函 ...