[JZOJ6340] 【NOIP2019模拟2019.9.4】B
题目
题目大意
给你个非负整数数列\(a\),每次等概率选择大于零的\(a_i\),使其减\(1\)。
问\(a_1\)被减到\(0\)的时候期望经过多少次操作。
思考历程
对于这题的暴力做法,显然可以状态压缩吧……
然后我突然意识到,实际上我们将题目转化成以下模型:
有\(n\)种颜色,第\(i\)种颜色的小球有\(a_i\)个。那么题目就变成了一个有重复元素的排列问题。
先将\(2\)到\(n\)排列求出来,然后考虑将\(1\)随机插入。
枚举最后一个\(1\)出现的位置,然后在前面用组合数计算插入的方案数。
这个做法打出来之后一直没有调出来,也不知道是我数学功底不好还是这个方法本来就是错的……
当然,即便是对的,也不会是满分做法。
正解
根据期望的线性性,题目可以转化为:对于每个\(i>1\),\(a_1\)减到\(0\)的时候\(a_i\)期望取了多少个。然后将每个\(i\)的这东西加起来,再加上\(a_1\),就是答案。
于是我们就只需要考虑这个问题。
接着就是最骚的操作:我们只考虑\(a_1\)和\(a_i\),其它被减掉对它们没有影响。它们有相等的概率被减\(1\),这个概率可以看做是\(\frac{1}{2}\)。于是相当于题目中\(n=2\)的情况。
现在考虑一个平面,一开始的坐标为\((a_1,a_i)\),每次随机地向下面或者左边走一格。
如果到达边界\((0,y)\),则会有\(a_i-y\)的贡献;如果到达边界\((x,0)\),则会有\(a_i\)的贡献。
对于边界\((0,y)\),设向下走了\(j\)步,则概率为\(\frac{C_{a_1+j-1}^{j}}{2^{a_1+j}}\)。
对于边界\((x,0)\),既然它们的贡献都一样,不妨将上面的和用\(1\)减掉,就是它的概率。
接着就可以列出一个式子……
列出之后容易发现,\((a_1,a_i+1)\)的答案可以\(O(1)\)地从\((a_i,a_i)\)转移过来。
代码
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#define N 500010
#define A 500010
#define mo 323232323
inline int input(){
char ch=getchar();
while (ch<'0' || '9'<ch)
ch=getchar();
int x=0;
do{
x=x*10+ch-'0';
ch=getchar();
}
while ('0'<=ch && ch<='9');
return x;
}
int n,a[N];
int fac[N+A],invf[N+A],inv2[N+A];
int ans1[A*3],ans2[A*3],ans[A*3];
inline int inv(int x){
int res=1;
for (int y=mo-2;y;y>>=1,x=(long long)x*x%mo)
if (y&1)
res=(long long)res*x%mo;
return res;
}
inline int C(int m,int n){return (long long)fac[m]*invf[n]%mo*invf[m-n]%mo;}
int main(){
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
n=input();
for (int i=1;i<=n;++i)
a[i]=input();
fac[0]=1,inv2[0]=1;
for (int i=1;i<=A*2;++i){
fac[i]=(long long)fac[i-1]*i%mo;
inv2[i]=(long long)inv2[i-1]*2%mo;
}
for (int i=0;i<=A*2;++i){
invf[i]=inv(fac[i]);
inv2[i]=inv(inv2[i]);
}
ans1[0]=ans2[0]=0;
for (int i=1;i<=A;++i){
ans1[i]=(ans1[i-1]+(long long)C(a[1]+i-2,i-1)*(i-1)%mo*inv2[a[1]+i-1]%mo)%mo;
ans2[i]=(ans2[i-1]+(long long)C(a[1]+i-2,i-1)*inv2[a[1]+i-1]%mo)%mo;
ans[i]=(ans1[i]+(long long)i*(1-ans2[i]+mo)%mo)%mo;
}
long long sum=a[1];
for (int i=2;i<=n;++i)
sum+=ans[a[i]];
printf("%lld\n",sum%mo);
return 0;
}
总结
期望的线性性真是奇妙啊……
[JZOJ6340] 【NOIP2019模拟2019.9.4】B的更多相关文章
- 6424. 【NOIP2019模拟2019.11.13】我的订书机之恋
题目描述 Description Input Output Sample Input 见下载 Sample Output 见下载 Data Constraint 题解 lj题卡线段树 求出每个右端点往 ...
- 6392. 【NOIP2019模拟2019.10.26】僵尸
题目描述 题解 吼题但题解怎么这么迷 考虑一种和题解不同的做法(理解) 先把僵尸离散化,h相同的钦(ying)点一个大小 (可以发现这样每种情况只会被算正好一次) 计算完全被占领的方案,然后1-方案/ ...
- 6389. 【NOIP2019模拟2019.10.26】小w学图论
题目描述 题解 之前做过一次 假设图建好了,设g[i]表示i->j(i<j)的个数 那么ans=∏(n-g[i]),因为连出去的必定会构成一个完全图,颜色互不相同 从n~1染色,点i的方案 ...
- 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]
题目描述 题解 随便bb 详细题解见 https://www.cnblogs.com/coldchair/p/11624979.html https://blog.csdn.net/alan_cty/ ...
- 6364. 【NOIP2019模拟2019.9.20】养马
题目描述 题解 一种显然的水法:max(0,-(点权-边权之和*2)) 这样会挂是因为在中途体力值可能会更小,所以考虑求走完每棵子树所需的至少体力值 考虑从子树往上推求出当前点的答案 设每棵子树从根往 ...
- 6362. 【NOIP2019模拟2019.9.18】数星星
题目描述 题解 一种好想/好写/跑得比**记者还快的做法: 对所有询问排序,按照R递增的顺序来处理 维护每个点最后一次被覆盖的时间,显然当前右端点为R时的答案为所有时间≥L的点的权值之和 LCT随便覆 ...
- 6359. 【NOIP2019模拟2019.9.15】小ω的树(tree)(定期重构)
题目描述 题解 qy的毒瘤题 CSP搞这种码农题当场手撕出题人 先按照边权从大到小建重构树,然后40%暴力修改+查找即可 100%可以定期重构+平衡规划,每次把B个询问拉出来建虚树,在虚树上暴力维护每 ...
- 【NOIP2019模拟2019.11.13】旅行 && GDKOI2018 还念(二分答案+dij)
Description: 题解: 显然满足二分性. 并且每一条边要不选l要不选r. 二分的那条链肯定要选l. 考虑有两个人在走最短路,一个人一开始必须走二分的那条链,要求第一个人走的比第二个人快. 安 ...
- 【NOIP2019模拟2019.10.07】果实摘取 (约瑟夫环、Mobius反演、类欧、Stern-Brocot Tree)
Description: 小 D 的家门口有一片果树林,果树上果实成熟了,小 D 想要摘下它们. 为了便于描述问题,我们假设小 D 的家在二维平面上的 (0, 0) 点,所有坐标范围的绝对值不超过 N ...
随机推荐
- 通过start.spring.io生成的springboot项目,导入IDE后POM第一行报错
通过problem控制台查看,显示unknown 尝试降低springboot版本,问题没了,应该是与maven jdk等版本冲突导致 这里JDK 1.8 mave 3.6.1 降低springb ...
- 【POJ】1679 The Unique MST
题目链接:http://poj.org/problem?id=1679 题意:给你一组数据,让你判断是否是唯一的最小生成树. 题解:这里用的是kuangbin大佬的次小生成树的模板.直接判断一下次小生 ...
- Python的序列化和反序列化
序列化是将dict---->str 反序列化是将str---->dict import jsonresult1 = json.dumps({'a': 1, 'b': 2}) #序列化res ...
- UserCF算法和ItemCF算法的对比
- C语言实现 冒泡排序 选择排序 希尔排序
// 冒泡排序 // 选择排序 // 希尔排序 // 快速排序 // 递归排序 // 堆排序 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h& ...
- MySQL 开始
安装,配置环境变量啥的,网上一抓一大堆,不说了.就说我再实际操作中遇到的问题. 1 添加自增列 点击apply,直接提示一个错误....百思不得其解..上图... 添加不了自增列....好恐怖.. ...
- spark出现BINLOG_FORMAT = STATEMENT
错误解决: Caused by: java.sql.SQLException: Cannot execute statement: impossible to write to binary log ...
- hive的行列互转
行转列 多行转多列 数据表 row2col col1 col2 col3 a c 1 a d 2 a e 3 b c 4 b d 5 b e 6 现在要将其转化为: col1 c d e a 1 2 ...
- NX二次开发-UFUN特征选择对话框UF_UI_select_feature
#include <uf.h> #include <uf_ui.h> UF_initialize(); //特征选择对话框 char sMessage[] = "特征 ...
- POJ2449-A*算法-第k短路
(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 题意:传送门 原题目描述在最下面. 给你一个有向图,求指定节点间的第k短路. 思路: 先反向跑出从终点开始的到每个节点的最短距离 ...