题目大意:你有$n$个操作和一个初始为$0$的变量$x$。

第$i$个操作为:以$P_i$的概率给$x$加上$A_i$,剩下$1-P_i$的概率给$x$乘上$B_i$。

你袭击生成了一个长度为$n$的排列$C$,并以此执行了第$C_1,C_2....C_n$个操作。

求执行完所有操作后,变量$x$的期望膜$998244353$的值。

数据范围:$n≤10^5,0≤P,A,B<998244353$

我太菜了

考虑如果并没有排列的要求,而是强行依次执行,会发生什么事情:

令$X_i$表示执行完前$i$个操作后$x$的期望。

则有:

$X_i=P_i\times (X_{i-1}+A_i)+(1-P_i)\times X_{i-1}\times B_i$

我们经过化简,得到:

$X_i=(P_i+B_i-P_i\times B_i)X_{i-1}+A_i\times B_i$

这个不就是一个一次函数吗?我们姑且将这个称为$F_i(x)$,我们将它表示为$F_i(x)=D_ix+E_i$

那么在不考虑顺序的情况下,则有:

$X_n=F_1(F_2(...F_n(0)...))$

然而求答案的时候,函数排列的顺序是随机的,对于任意的$i≠j$,函数i排在函数j前面的概率都是$\frac{1}{2}$。

我们只需要求出,对于每个$E_i$,套在$F_i(x)$外面的函数的积的期望。

基于这些,则有:

$X_n=\frac{1}{n!}\sum \limits_{i=1}^{n} E_i \sum \limits_{j=1}^{n} [x^j] \prod \limits_{k=1,k\not\equiv i}^{n}(1+D_k)$

然后,我们通过分治FFT求解这个式子即可。

 #include<bits/stdc++.h>
#define MOD 998244353
#define G 3
#define L long long
#define M 262144
using namespace std; L pow_mod(L x,L k){L ans=; for(;k;k>>=,x=x*x%MOD) if(k&) ans=ans*x%MOD; return ans;}
void chage(int a[],int n){
for(int i=,j=;i<n-;i++){
if(i<j) swap(a[i],a[j]);
int k=n>>;
while(j>=k) j-=k,k>>=;
j+=k;
}
}
inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:a+b;}
inline int mns(int a,int b){return a<b?a-b+MOD:a-b;}
void NTT(int a[],int n,int on){
chage(a,n);
for(int h=;h<=n;h<<=){
int wn=pow_mod(G,(MOD-)/h);
for(int j=;j<n;j+=h){
int w=;
for(int k=j;k<j+(h>>);k++){
int u=a[k],t=1LL*a[k+(h>>)]*w%MOD;
//a[k]=(u+t)%MOD; a[k+(h>>1)]=(u-t+MOD)%MOD;
a[k]=pls(u,t); a[k+(h>>)]=mns(u,t);
w=1LL*w*wn%MOD;
}
}
}
if(on==-){
L inv=pow_mod(n,MOD-);
reverse(a+,a+n);
for(int i=;i<n;i++) a[i]=1LL*a[i]*inv%MOD;
}
}
void MUL(int ans[],int a[],int lena,int b[],int lenb){
static int t1[M],t2[M];
int len=; while(len<=lena+lenb) len<<=;
memset(t1,,len<<); memcpy(t1,a,(lena+)<<);
memset(t2,,len<<); memcpy(t2,b,(lenb+)<<);
NTT(t1,len,); NTT(t2,len,);
for(int i=;i<len;i++) t1[i]=1LL*t1[i]*t2[i]%MOD;
NTT(t1,len,-);
memcpy(ans,t1,(lena+lenb+)<<);
} L D[M]={},E[M]={},fac[M]={};
void solve(int f[],int g[],int l,int r){
static int h[M];
if(l==r) return f[]=E[l],g[]=D[l],g[]=,void();
int mid=(l+r)>>,lenl=mid-l+,lenr=r-mid;
solve(f,g,l,mid); solve(f+lenl+,g+lenl+,mid+,r);
MUL(h,f,lenl-,g+lenl+,lenr);
MUL(f,f+lenl+,lenr-,g,lenl);
for(int i=;i<=r-l+;i++) f[i]=(f[i]+h[i])%MOD;
MUL(g,g,lenl,g+lenl+,lenr);
} int ff[M]={},gg[M]={};
int main(){
fac[]=; for(int i=;i<M;i++) fac[i]=fac[i-]*i%MOD;
int n; scanf("%d",&n);
for(int i=;i<=n;i++){
L P,B,A; scanf("%lld%lld%lld",&P,&A,&B);
D[i]=(P+B-P*B%MOD+MOD)%MOD;
E[i]=A*P%MOD;
}
solve(ff,gg,,n);
L ans=;
for(int i=;i<n;i++) (ans+=1LL*ff[i]*fac[i]%MOD*fac[n-i-])%=MOD;
ans=ans*pow_mod(fac[n],MOD-)%MOD;
cout<<ans<<endl;
}

【2019北京集训测试赛(七)】 操作 分治+FFT+生成函数的更多相关文章

  1. 【2019北京集训测试赛(十三)】数据(sj) 冷静分析

    题目大意:给你一个代表区间$[1,n]$的线段树,问你随机访问区间$[1,n]$中的一个子区间,覆盖到的线段树节点个数的期望(需要乘上$\frac{n(n-1)}{2}$后输出). 数据范围:$n≤1 ...

  2. [2016北京集训测试赛5]小Q与内存-[线段树的神秘操作]

    Description Solution 哇真的异常服气..线段树都可以搞合并和拆分的啊orzorz.神的世界我不懂 Code #include<iostream> #include< ...

  3. 2016北京集训测试赛(七)Problem A: 自动机

    Solution 注意到这一题并不要求字符串最短或者是字典序最小, 因此直接构造就可以了. 我们对于每个点\(u \ne 0\)找到一个串\(S\), 使得\(T(u, S) = T(0, S)\), ...

  4. [2016北京集训测试赛7]isn-[树状数组+dp+容斥]

    Description Solution 定义dp[i][j]为在1到i个数中选了j个数,并且保证选了i的选法总数. dp[i][j]为所有满足A[k]>A[i]的k(k<i)的dp[k] ...

  5. 2016北京集训测试赛(十七)Problem B: 银河战舰

    Solution 好题, 又是长链剖分2333 考虑怎么统计答案, 我场上的思路是统计以一个点作为结尾的最长上升链, 但这显然是很难处理的. 正解的方法是统计以每个点作为折弯点的最长上升链. 具体的内 ...

  6. BZOJ 4543 2016北京集训测试赛(二)Problem B: thr 既 长链剖分学习笔记

    Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同 ...

  7. BZOJ 4543 2016北京集训测试赛(二)Problem B: thr

    Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同 ...

  8. 【2016北京集训测试赛(十)】 Azelso (期望DP)

    Time Limit: 1000 ms   Memory Limit: 256 MB Description 题解 状态表示: 这题的状态表示有点难想...... 设$f_i$表示第$i$个事件经过之 ...

  9. 【2016北京集训测试赛(二)】 thr (树形DP)

    Description 题解 (这可是一道很早就碰到的练习题然后我不会做不想做,没想到在Contest碰到欲哭无泪......) 题目大意是寻找三点对的个数,使得其中的三个点两两距离都为d. 问题在于 ...

随机推荐

  1. 大数据入门到精通12--spark dataframe 注册成hive 的临时表

    一.获得最初的数据并形成dataframe val ny= sc.textFile("data/new_york/")val header=ny.firstval filterNY ...

  2. java学习笔记(五):公共类

    什么是公共类,公共类就是和源文件名同名的类,举例来说:类的名称是 public class aaa{},那么源文件就应该是 aaa.java. 每个源文件中只能有一个公共类. 每个源文件可以有很多非公 ...

  3. 【Django】HTTP status code must be an integer.

    刚刚出现这个问题,还以为是表单提交或者什么网络错误 结果发现是自己的低级错误写了 HttpResponse(request,'sigin_result2.html',context)这个根本不能渲染模 ...

  4. (转)Android四大组件——Activity跳转动画、淡出淡入、滑出滑入、自定义退出进入

    文章转自:http://blog.csdn.net/qq_30379689/article/details/52494270 Activity跳转动画.淡入淡出.滑入滑出.自定义退出进入 前言: 系统 ...

  5. concurrent.futures模块(进程池/线程池)

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  6. squid常用操作

    如何查看squid的缓存命中率 使用命令: squidclient -h host -p port mgr:info比如: /usr/local/squid/bin/squidclient -h 12 ...

  7. Event对象和触发

    1.构造: //非IE浏览器事件构造方法 var event = document.createEvent('HTMLEvents');//'HTMLEvents'自定义事件名 //IE浏览器构造方法 ...

  8. ActiveMQ_5死信队列

    activemq死信队列 DLQ-死信队列(Dead Letter Queue)用来保存处理失败或者过期的消息. 出现以下情况时,消息会被redelivered: A transacted sessi ...

  9. linux 查看内网流量

    可以使用iftop进行Linux机器的网络流量监控 安装方法 centos系统下 第一步:安装EPEL源 yum install epel-release 第二部:安装iftop yum instal ...

  10. javascript跨域传递消息 / 服务器实时推送总结

    参考文档,下面有转载[非常好的两篇文章]: http://www.cnblogs.com/loveis715/p/4592246.html [跨源的各种方法总结] http://kb.cnblogs. ...