Description

给定两个长度分别为 \(n\) 和 \(m\) 的序列 \(a\) 和 \(b\)。要从这两个序列中分别随机一个数,设为 \(a_x,b_y\),定义该次游戏的 \(k\) 次收益为 \((a_x+b_y)^k\) 。对于 \(i=1,2,\dots,t\),求一次游戏 \(i\) 次收益的期望。\(n,m,t\leq 10^5\)。

Sol

根据期望的线性性,显然可以求每个点对的 \(i\) 次收益,最后再除以 \(nm\) 就好了。

所以问题转化为,对于每个 \(k\),求:

\[\sum_{i=1}^n\sum_{j=1}^m (a_i+b_j)^k
\]

接下来直接推导:

\[\begin{aligned}
ans_k&=\sum_{i=1}^n\sum_{j=1}^m (a_i+b_j)^k\\
&=\sum_{i=1}^n\sum_{j=1}^m\sum_{p=0}^k \binom kpa_i^pb_j^{k-p}\\
&=\sum_{p=0}^k\binom kp \left(\sum_{i=1}^na_i^p\right) \left(\sum_{j=1}^mb_j^{k-p} \right)\\
&=k!\cdot\sum_{p=0}^k \left(\sum_{i=1} ^n \frac{a_i^p}{p!}\right) \left(\sum_{j=1}^m\frac{b_j^{k-p}}{(k-p)!} \right) \end{aligned}
\]

发现这是个卷积式子,现在问题变成了如何求:

\[\sum_{i=1}^n a_i^p
\]

设 \(F(x)=\prod\limits_{i=1}^n(1+a_ix),G(x)=\ln(F(x))\)

那么:

\[\begin{aligned}
G(x)&=\ln(\prod_{i=1}^n 1+a_ix)\\
&=\sum_{i=1}^n \ln(1+a_ix)
\end{aligned}
\]

把 \(\ln(1+a_ix)\) 泰勒展开:

\[\begin{aligned}
G(x)&=\sum_{i=1}^n \ln(1+a_ix)\\
&= \sum_{i=1}^n \sum_{k=1}^\infty \frac{(-1)^{k+1}}{k}\cdot a_i^k\cdot x^k\\
&= \sum_{k=1}^\infty \frac{(-1)^{k+1}}k\cdot x^k\cdot \left( \sum_{i=1}^n a_i^k \right)
\end{aligned}
\]

后边那项就是我们要求的。

总结一下,先分治\(\text{NTT}\)求出\(F(x)\),再取对数求出\(G(x)\),然后第 \(k\) 项乘上一个系数就是 \(\sum\limits_{i=1}^n a_i^k\) 了。

Code

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
typedef vector<int> vec;
const int N=262144+5;
const int mod=998244353;
#define pb push_back int w[2][N],in[N];
int fac[N],ifac[N],A[N],B[N];
int n,m,t,a[N],b[N],c[N],d[N];
int lim,maxn,rev[N],tmpa[N],tmpb[N]; int ksm(int a,int b=mod-2,int ans=1){
while(b){
if(b&1) ans=1ll*ans*a%mod;
a=1ll*a*a%mod;b>>=1;
} return ans;
} void ntt(int *f,int g){
for(int i=1;i<lim;i++) if(i<rev[i]) swap(f[i],f[rev[i]]);
for(int mid=1;mid<lim;mid<<=1){
for(int R=mid<<1,j=0;j<lim;j+=R){
for(int k=0;k<mid;k++){
int x=f[j+k],y=1ll*w[g][maxn/R*k]*f[j+k+mid]%mod;
f[j+k]=x+y>=mod?x+y-mod:x+y,f[j+k+mid]=x-y<0?x-y+mod:x-y;
}
}
} if(g)
for(int i=0;i<lim;i++) f[i]=1ll*f[i]*in[lim]%mod;
} vec calc(int *a,int l,int r){
if(l==r){vec now;now.pb(1);now.pb(a[l]);return now;}
int mid=l+r>>1;
vec L=calc(a,l,mid),R=calc(a,mid+1,r);
lim=1;while(lim<=r-l+1) lim<<=1;
for(int i=1;i<lim;i++) rev[i]=(rev[i>>1]>>1)|(i&1?lim>>1:0);
for(int i=0;i<(int)L.size();i++) A[i]=L[i];
for(int i=0;i<(int)R.size();i++) B[i]=R[i];
ntt(A,0),ntt(B,0);
for(int i=0;i<lim;i++) A[i]=1ll*A[i]*B[i]%mod;
ntt(A,1); vec now;
for(int i=0;i<=r-l+1;i++) now.pb(A[i]),A[i]=B[i]=0;
for(int i=r-l+2;i<lim;i++) A[i]=B[i]=0;
return now;
} void solveinv(int *a,int *b,int len){
if(len==1) return b[0]=ksm(a[0]),void();
solveinv(a,b,len>>1); lim=len<<1;
for(int i=1;i<lim;i++) rev[i]=(rev[i>>1]>>1)|(i&1?lim>>1:0);
for(int i=len;i<lim;i++) A[i]=0;
for(int i=0;i<len;i++) A[i]=a[i];
ntt(A,0),ntt(b,0);
for(int i=0;i<lim;i++)
b[i]=1ll*b[i]*(2ll-1ll*A[i]*b[i]%mod+mod)%mod;
ntt(b,1); for(int i=len;i<lim;i++) b[i]=0;
} void ds(int *a,int *b,int n){
for(int i=0;i<n;i++)
b[i]=1ll*a[i+1]*(i+1)%mod;
b[n]=0;
} void jf(int *a,int n){
for(int i=n;i;i--)
a[i]=1ll*a[i-1]*in[i]%mod;
a[0]=0;
} void solveln(int *a,int *b,int n){
memset(tmpa,0,sizeof tmpa);
memset(tmpb,0,sizeof tmpb);
lim=1;while(lim<n) lim<<=1;
solveinv(a,tmpa,lim);
lim=1;while(lim<n<<1) lim<<=1;
for(int i=1;i<lim;i++) rev[i]=(rev[i>>1]>>1)|(i&1?lim>>1:0);
ds(a,tmpb,n);
ntt(tmpa,0),ntt(tmpb,0);
for(int i=0;i<lim;i++) b[i]=1ll*tmpa[i]*tmpb[i]%mod;
ntt(b,1); jf(b,n);
} void init(int n){
fac[0]=ifac[0]=1;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
ifac[n]=ksm(fac[n]);
for(int i=n-1;i;i--) ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
} signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++) scanf("%d",&b[i]);
scanf("%d",&t);
init(t);
maxn=1;while(maxn<=max(t<<1,n+m-2)) maxn<<=1;
w[0][0]=w[1][0]=1; in[1]=1;
w[0][1]=ksm(3,(mod-1)/maxn),w[1][1]=ksm((mod+1)/3,(mod-1)/maxn);
for(int i=2;i<=maxn;i++)
in[i]=ksm(i),
w[0][i]=1ll*w[0][i-1]*w[0][1]%mod,
w[1][i]=1ll*w[1][i-1]*w[1][1]%mod;
vec aa=calc(a,1,n),bb=calc(b,1,m);
for(int i=0;i<=n;i++) c[i]=aa[i];
for(int i=0;i<=m;i++) d[i]=bb[i];
memset(a,0,sizeof a),memset(b,0,sizeof b);
solveln(c,a,t); a[0]=n; // 注意这里的0次项 积分给消掉了 所以要特殊赋值
solveln(d,b,t); b[0]=m;
for(int i=1;i<=t;i++){
a[i]=1ll*a[i]*i%mod;
b[i]=1ll*b[i]*i%mod;
if(!(i&1)) a[i]=mod-a[i],b[i]=mod-b[i];
a[i]=1ll*a[i]*ifac[i]%mod;
b[i]=1ll*b[i]*ifac[i]%mod;
}
for(int i=t+1;i<lim;i++) a[i]=b[i]=0;
lim=maxn;
for(int i=1;i<lim;i++) rev[i]=(rev[i>>1]>>1)|(i&1?lim>>1:0);
ntt(a,0),ntt(b,0);
for(int i=0;i<lim;i++) a[i]=1ll*a[i]*b[i]%mod;
ntt(a,1);
for(int inn=ksm(1ll*n*m%mod),i=1;i<=t;i++)
printf("%lld\n",1ll*a[i]*fac[i]%mod*inn%mod);
return 0;
}

[Luogu4705] 玩游戏的更多相关文章

  1. luogu4705玩游戏

    题解 我们要对于每个t,求一个(1/mn)sigma(ax+by)^t. 把系数不用管,把其他部分二项式展开一下: simga(ax^r*by^(t-r)*C(t,r)). 把组合数拆开,就变成了一个 ...

  2. Luogu4705 玩游戏 分治FFT

    传送门 \(\begin{align*} Ans_k &= \sum\limits_{i=1}^n\sum\limits_{j=1}^m (a_i + b_j)^k \\ &= \su ...

  3. 原生JS实战:写了个一边玩游戏,一边记JS的API的游戏

    本文是苏福的原创文章,转载请注明出处:苏福CNblog:http://www.cnblogs.com/susufufu/p/5878913.html 本程序[一边玩游戏,一边记JS的API]是本人的个 ...

  4. bzoj4730: Alice和Bob又在玩游戏

    Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ...

  5. 小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和

    小易邀请你玩一个数字游戏,小易给你一系列的整数.你们俩使用这些整数玩游戏.每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字. 例如: 如果{2,1,2 ...

  6. cdoj 1136 邱老师玩游戏 树形背包

    邱老师玩游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1136 Desc ...

  7. win7系统玩游戏不能全屏的解决办法

    1.修改注册表中的显示器的参数设置   Win键+R键,打开运行窗口,输入regedit回车,这样就打开了注册表编辑器,然后,定位到以下位置:   HKEY_LOCAL_MACHINE\SYSTEM\ ...

  8. 【用PS3手柄在安卓设备上玩游戏系列】连接手柄和设备

    背景 硬件要求1:PS3 手柄 + 手柄配套的USB线 硬件要求2:已经获得 ROOT 权限并且支持蓝牙的安卓设备 软件要求1:Sixaxis Compatibility Checker PS3 手柄 ...

  9. UESTC_邱老师玩游戏 2015 UESTC Training for Dynamic Programming<Problem G>

    G - 邱老师玩游戏 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

随机推荐

  1. 181102 Python环境搭建(安装Sublime Text3)

    利用Pycharm来编写.执行python代码是一个不错的选择,Pycharm的安装的确也很方便.但是偶然看到别人用Sublime Text来编写.执行代码,觉得很酷.所以自己动手搭建环境. 1. 下 ...

  2. Windows下安装Kafka

    一.安装JDK 二.安装zooeleeper 下载安装包:http://zookeeper.apache.org/releases.html#download 下载后解压到一个目录: 1.进入Zook ...

  3. Reveal : Xcode辅助界面调试工具

    Reveal简介: Reveal是一款iOS界面调试工具,辅助Xcode进行界面调试,使用它可以在iOS开发的时候动态的查看和修改应用程序的界面. 软件下载 首先去官网下载Reveal,下载地址:ht ...

  4. LeetCode笔记:140. Word Break II

    题目描述 给定一个非空的字符串s,一个非空的字符串list作为字典.通过在s中添加空格可以将s变为由list中的word表示的句子,要求返回所有可能组成的句子.设定list中的word不重复,且每一个 ...

  5. JS监听对象属性改变

    设想这么一个需求: user.name = '张三' 对user数据进行操作的时候,同步的修改页面上的用户名为张三. 这就是个数据绑定的概念. 针对这类需求 ES5提供了Object.definePr ...

  6. 阿里面试100%问到,JVM性能调优篇

    JVM 调优概述 性能定义 吞吐量 - 指不考虑 GC 引起的停顿时间或内存消耗,垃圾收集器能支撑应用达到的最高性能指标. 延迟 - 其度量标准是缩短由于垃圾啊收集引起的停顿时间或者完全消除因垃圾收集 ...

  7. FFmpeg 学习(四):FFmpeg API 介绍与通用 API 分析

    一.FFmpeg 相关术语 1. 容器/文件(Container/File):即特定格式的多媒体文件,比如MP4,flv,mov等. 2. 媒体流(Stream):表示在时间轴上的一段连续的数据,比如 ...

  8. [Swift]LeetCode296. 最佳开会地点 $ Best Meeting Point

    A group of two or more people wants to meet and minimize the total travel distance. You are given a ...

  9. awk小例子_2_数值统计脚本

    通信公司工作,经常处理各种协议接口,在统计协议接口字段内容时,需要统计字段填写的内容是否正确,和占比是多少.要是单次统计,估计会把人累死,写个脚本统计,轻松便捷. 举例:接口内容 这是一条话单,这样的 ...

  10. 用sklearn封装的kmeans库

    由于需要海量的进行聚类,所以将 k-means 算法自我封装成一个方便利用的库,可以直接调用得到最优的 k值 和 中心点: #!/usr/bin/python3.4 # -*- coding: utf ...