题目描述

有一道选择题,有 a,b,c,d 四个选项。

现在有 n 个人来做这题,第 i 个人有 pi,j 的概率选第 j 个选项。

定义\(cnt(x)\)为选第$ x $个选项的人数。

令\(mx\)为\(cnt(x)\)最大的\(x\)(如果有多个\(cnt(x)\)最大的$ x$,则取其中 \(x\) 最小的),若 ,则所有人得 \(0\) 分;否则令 choicei 表示第$ i $个人选的选项,则第 i 人得 分。

求每个人的期望得分。

输入描述:

第一行一个整数 n ,表示人数。

接下来 n 行,每行 4 个整数,其中第 \(i\) 行第 \(j\) 个数表示 \(p_{i,j}\) ,即在模 \(998244353\) 意义下第 i 个人选第 j 个选项的概率。

接下来 4 行,每行 4 个整数,第 \(i\) 行第 \(j\) 个数表示 \(w_{i,j}\) 。

输出描述:

共 n 行,第 i 行表示第 i 个人在模 \(998244353\) 意义下的期望得分。

示例1

输入

2
499122177 499122177 0 0
332748118 665496236 0 0
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

输出

166374061
166374061

说明

第一个人选第 1,2,3,4 个选项的概率分别为

第二个人选第 1,2,3,4 个选项的概率分别为

当他们选择不同选项时, ,所有人得分为 \(0\) ;

当他们都选第 1 个选项时,概率为 (1/2)*(1/3)=1/6,两个人的得分都是 \(w_{1,1}=1\);

当他们都选第 2 个选项时,概率为 ,两个人的得分都是 \(w_{2,2}=6\) 。

所以两个人的期望得分都是 , 模 \(998244353=166374061\) 。

Solution

首先循环枚举每个选项\(a\)。

我们设\(f[i][j]\)表示前\(i\)个人有\(j\)人选了这个选项的概率,\(g[i][j]\)表示后\(i\)个人有\(j\)人选了这个选项的概率。转移是很显然的吧。

\[f[i][j]=f[i-1][j-1]\times p[i][a]+f[i-1][j]\times (1-p[i][a])\quad f[0][0]=1
\]

\[g[i][j]=g[i+1][j-1]\times p[i][a]+g[i+1][j]\times (1-p[i][a])\quad g[n+1][0]=1
\]

然后我们考虑对\(g\)的第二维做个后缀和或者对\(f\) 的第二维做个前缀和。我们拿做\(g\)来说。那么\(g[i][j]\)的意义就变成了后\(i\)个人,选了这个选项的人数不少于\(j\)个的概率。

然后枚举每一个人,对每一个人,再枚举这个人前面有多少人选这一项,然后下面就不用再说了吧,非常显然的搞一下就好了。

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define REP(i,a,n) for(register int i=(a);i<=(n);++i)
#define PER(i,a,n) for(register int i=(a);i>=(n);--i)
#define FEC(i,x) for(register int i=head[x];i;i=g[i].ne)
template<typename A>inline void read(A&a){a=0;char c=0;int f=1;while(c<'0'||c>'9')(c=getchar())=='-'?f=-1:0;while(c>='0'&&c<='9')a=(a<<3)+(a<<1)+c-'0',c=getchar();f==-1?a=-a:0;}
char buf[30];template<typename A>inline void write(A a){if(a<0)putchar('-'),a=-a;int top=0;if(!a)buf[top=1]='0';while(a)buf[++top]=a%10+'0',a/=10;while(top)putchar(buf[top--]);}
typedef long long ll;typedef unsigned long long ull;
template<typename A,typename B>inline bool SMAX(A&x,const B&y){return y>x?x=y,1:0;}
template<typename A,typename B>inline bool SMIN(A&x,const B&y){return y<x?x=y,1:0;} const int N=2000+7,MOD=998244353;
int n,m,p[N][4],w[4][4],f[N][N],g[N][N],ans[N];
template<typename A,typename B>inline void SADD(A&x,const B&y){x+=y;x>=MOD?x-=MOD:0;} int main(){
read(n);m=(n>>1)+1;
for(register int i=1;i<=n;++i)read(p[i][0]),read(p[i][1]),read(p[i][2]),read(p[i][3]);
for(register int i=0;i<4;++i)read(w[i][0]),read(w[i][1]),read(w[i][2]),read(w[i][3]);
for(register int c=0;c<4;++c){
memset(f,0,sizeof(f));memset(g,0,sizeof(g));f[0][0]=1;g[n+1][0]=1;
for(register int i=1;i<=n;++i)
for(register int j=0;j<=i;++j)f[i][j]=((j?(ll)f[i-1][j-1]*p[i][c]%MOD:0)+(ll)f[i-1][j]*(MOD+1-p[i][c])%MOD)%MOD;
for(register int i=n;i;--i)
for(register int j=0;j<=n-i+1;++j)g[i][j]=((j?(ll)g[i+1][j-1]*p[i][c]%MOD:0)+(ll)g[i+1][j]*(MOD+1-p[i][c])%MOD)%MOD;
for(register int i=1;i<=n;++i)
for(register int j=n-i;~j;--j)SADD(g[i][j],g[i][j+1]);
for(register int i=1;i<=n;++i){
for(register int j=0;j<=i;++j)
for(register int k=0;k<4;++k)SADD(ans[i],(ll)f[i-1][j]*g[i+1][m-j-(k==c)>=0?m-j-(k==c):0]%MOD*p[i][k]%MOD*w[c][k]%MOD);
}
}
for(register int i=1;i<=n;++i)write(ans[i]),putchar('\n');
}

牛客网NOIP赛前集训营-提高组(第六场)B-选择题的更多相关文章

  1. 牛客网NOIP赛前集训营-普及组(第二场)和 牛客网NOIP赛前集训营-提高组(第二场)解题报告

    目录 牛客网NOIP赛前集训营-普及组(第二场) A 你好诶加币 B 最后一次 C 选择颜色 D 合法括号序列 牛客网NOIP赛前集训营-提高组(第二场) A 方差 B 分糖果 C 集合划分 牛客网N ...

  2. 牛客网NOIP赛前集训营-提高组(第二场)A 方差

    链接:https://www.nowcoder.com/acm/contest/173/A来源:牛客网 题目描述 一个长度为 m 的序列 b[1...m] ,我们定义它的方差为 ,其中  表示序列的平 ...

  3. [牛客网NOIP赛前集训营-提高组(第一场)]C.保护

    链接:https://www.nowcoder.com/acm/contest/172/C来源:牛客网 题目描述 C国有n个城市,城市间通过一个树形结构形成一个连通图.城市编号为1到n,其中1号城市为 ...

  4. 牛客网NOIP赛前集训营-提高组(第一场)

    牛客的这场比赛感觉真心不错!! 打得还是很过瘾的.水平也比较适合. T1:中位数: 题目描述 小N得到了一个非常神奇的序列A.这个序列长度为N,下标从1开始.A的一个子区间对应一个序列,可以由数对[l ...

  5. 比赛总结——牛客网 NOIP赛前集训营提高组模拟第一场

    第一场打的很惨淡啊 t1二分+前缀最小值没想出来,20分的暴力也挂了,只有10分 t2数位dp,调了半天,结果因为忘了判0的特殊情况WA了一个点,亏死 t3emmmm.. 不会 imone说是DSU ...

  6. 牛客网NOIP赛前集训营-提高组(第一场)B 数数字

    数数字 思路: 数位dp 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...

  7. 牛客网NOIP赛前集训营-提高组(第一场)A 中位数

    中位数 思路: 二分答案 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...

  8. 牛客网NOIP赛前集训营 提高组 第5场 T2 旅游

    [题解] 我们可以发现不在最小生成树上的边一定不能多次经过,因为一条不在最小生成树上的边(u,v)的边权比最小生成树上(u,v)之间的路径更长,选择不在最小生成树上的边一定不划算. 我们还需要确定最小 ...

  9. 牛客网NOIP赛前集训营-提高组(第四场)游记

    牛客网NOIP赛前集训营-提高组(第四场)游记 动态点分治 题目大意: \(T(t\le10000)\)组询问,求\([l,r]\)中\(k(l,r,k<2^{63})\)的非负整数次幂的数的个 ...

  10. 牛客网NOIP赛前集训营-提高组(第四场)B区间

    牛客网NOIP赛前集训营-提高组(第四场)B区间 题目描述 给出一个序列$ a_1  \dots   a_n$. 定义一个区间 \([l,r]\) 是好的,当且仅当这个区间中存在一个 \(i\),使得 ...

随机推荐

  1. SQL Server数据库的软硬件性能瓶颈

    在过去十年里,很多复杂的企业应用都是用Microsoft SQL Server进行开发和部署的.如今,SQL Server已经成为现代业务应用的基石,并且它还是很多大公司业务流程的核心.SQL Ser ...

  2. 浅谈MySQL优化

    本文整理了一些MySQL的通用优化方法,做个简单的总结分享,旨在帮助那些没有专职MySQL DBA的企业做好基本的优化工作,至于具体的SQL优化,大部分通过加适当的索引即可达到效果,更复杂的就需要具体 ...

  3. WPF 设置窗体大小为显示器工作区域大小

      最近做的项目遇到一个问题,窗体在1680*1050分辨率下显示,系统字体设置为小字体时,显示没问题,但是调到中等字体时,窗体显示位置出了问题.主窗体为无边框窗体,拖动及放大缩小事件都是自己写的. ...

  4. JS对象、原型、this学习总结

    1.对象是函数创建的,而函数却又是一种对象.(属性的集合) 2.每个函数都有一个属性叫做prototype.这个prototype的属性值是一个对象,默认的只有一个constructor的属性,指向这 ...

  5. Java控制台输入字符串及字符串比较

    需求描述:茵茵很喜欢研究车牌号码,从车牌号码上可以看出号码注册的早晚,据研究发现,车牌号码是按字典序发放的,现在她收集了很多车牌号码,请你设计程序帮她判断注册较早的号码.车牌号码由5个字母或数字组成. ...

  6. EZOJ #375高速公路

    分析 我们可以先跑一遍全价的最短路 之后我们枚举这个第k大的价格w[i] 将其它边减这个边的权值和0取max 在跑出最短路之后加上减去的费用,即w[i]*k 我们发现如果价值大于w[i]的边小于k个 ...

  7. django中的url控制

    1.django中的第一个控件:url控制  (路由分发) urls.py:请求路径与视图函数的之间的关系 步骤: 1.首先是要配置环境,   2.其次就是引路径   3.在视图的文件夹里面写相应的函 ...

  8. 20150722---点击按钮使指定的控件可见部分平移(JS)

    前段代码: <div id="out" style=" width:400px;overflow:hidden;"> <div id=&quo ...

  9. ES6中set的用法回顾

    ES6中的set类似一个数组,但是其中的值都是唯一的,Set本身是一个构造函数,用来生成 Set 数据结构. set函数可以接受一个数组作为参数,用来初始化: const set = new Set( ...

  10. mysql行锁和死锁检测

    行锁顾名思义,就是针对单行数据加锁,在mysql中,锁的实现是由引擎层实现的,MyISAM引擎就不支持行锁 不支持行锁就意味着并发控制只能使用表锁,也就是说同一时间,在这个表上只能有一个更新在执行,这 ...