Luogu 4705 玩游戏
看见这个题依稀想起了$5$月月赛时候的事情,到现在仍然它感觉非常神仙。
游戏$k$次价值的期望答案
$$ans_k = \frac{1}{nm}\sum_{i = 1}^{n}\sum_{j = 1}^{n}(a_i + b_j)^k$$
二项式定理展开
$$ans_k=\frac{1}{nm}\sum_{i = 1}^{n}\sum_{j = 1}^{m}\sum_{t = 0}^{k}\binom{k}{t}a_i^tb_j^{k - t}$$
$$ = \frac{1}{nm}\sum_{t = 0}^{k}\binom{k}{t}\sum_{i = 1}^{n}a_i^t\sum_{j = 1}^{m}b_j^{k - t}$$
$$= \frac{k!}{nm}\frac{\sum_{i = 1}^{n}a_i^t}{t!}\frac{\sum_{j = 1}^{m}b_j^{k - t}}{(k - t)!}$$
容易发现这后面是一个卷积的形式。
我们设$A(x) = \frac{\sum_{i = 1}^{n}a_i^x}{x!}$,$B(x) = \frac{\sum_{i = 1}^{n}b_i^x}{x!}$,答案就变成了
$$\frac{k!}{nm}(A * B)(k)$$
现在考虑怎么算这个$\sum_{i = 1}^{n}a_i^k$。
不会了,点开题解
我们构造一个多项式$F(x) = \prod_{i = 1}^{n}(1 - a_ix)$,这个$F(x)$可以通过分治算出来,时间复杂度$T(n) = 2T(\frac{n}{2}) + O(nlogn)$趋向$O(nlogn)$???。
接下来要开始变魔术了,
设$G(x) = lnF(x)$,
$$G(x) = \sum_{i = 1}^{n}ln(1 - a_ix)$$
对里面的$ln$在$x_0 = 0$处泰勒展开。
我们知道
$$ln(1 - x) = 0 - \frac{x}{1} - \frac{x^2}{2} - \frac{x^3}{3} - \cdots = -\sum_{i = 1}^{\infty}\frac{x^i}{i}$$
所以
$$G(x) = \sum_{i = 1}^{n}\sum_{j = 1}^{k}-\frac{a_i^j}{j}x^j$$
因为这个题对$x^{k + 1}$次取模了,所以后面的项可以不用再写了。
变形一下
$$G(x) = \sum_{j = 1}^{k}(-\frac{1}{j}\sum_{i = 1}^{n}a_i^j)x^j$$
发现$1$到$k$的$\sum_{i = 1}^{n}a_i^k$直接算出来了,而$i = 0$时候这东西显然为$n$。
鼓掌~~~
现在回过头来考虑一下这个魔术是怎么变出来的。
考虑构造每一个$a_i$的生成函数
$$1 + a_ix + a_i^2x^2 + a_i^3x^3 + \cdots$$
把每一个$a_i$的生成函数都构造出来然后加起来的第$i$项系数就是$k = i$时候的答案了。
$$F(x) = \sum_{i = 1}^{n}\frac{1}{1 - a_ix}$$
发现这个$F(x)$并不是很好算,而
$$ln'(1 - a_ix) = \frac{1}{1 - a_ix}$$
$$(ln(1 - a_ix))' = \frac{-a_i}{1 - a_ix}$$
所以先计算
$$G(x) = \sum_{i = 1}^{n}\frac{-a_i}{1 - a_ix} = (ln\prod_{i = 1}^{n}(1 - a_ix))'$$
把这两个式子写回到生成函数的形式,发现
$$F(x) = -x * G(x) + n$$
于是大功告成。
用$vector$写多项式真爽。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
typedef vector <ll> poly; const int N = 1e5 + ;
const int Maxn = 1e5; int n, m, K;
ll a[N], b[N], fac[N], ifac[N], inv[N]; template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for (; ch > '' || ch < ''; ch = getchar())
if (ch == '-') op = -;
for (; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void deb(poly c) {
for (int i = ; i < (int)c.size(); i++)
printf("%lld%c", c[i], " \n"[i == (int)c.size() - ]);
} namespace Poly {
const int L = << ;
const ll P = 998244353LL; int lim, pos[L]; inline ll fpow(ll x, ll y) {
ll res = ;
for (; y > ; y >>= ) {
if (y & ) res = res * x % P;
x = x * x % P;
}
return res;
} template <typename T>
inline void inc(T &x, T y) {
x += y;
if (x >= P) x -= P;
} template <typename T>
inline void sub(T &x, T y) {
x -= y;
if (x < ) x += P;
} inline void prework(int len) {
int l = ;
for (lim = ; lim < len; lim <<= , ++l);
for (int i = ; i < lim; i++)
pos[i] = (pos[i >> ] >> ) | ((i & ) << (l - ));
} inline void ntt(poly &c, int opt) {
c.resize(lim, );
for (int i = ; i < lim; i++)
if (i < pos[i]) swap(c[i], c[pos[i]]);
for (int i = ; i < lim; i <<= ) {
ll wn = fpow(, (P - ) / (i << ));
if (opt == -) wn = fpow(wn, P - );
for (int len = i << , j = ; j < lim; j += len) {
ll w = ;
for (int k = ; k < i; k++, w = w * wn % P) {
ll x = c[j + k], y = w * c[j + k + i] % P;
c[j + k] = (x + y) % P, c[j + k + i] = (x - y + P) % P;
}
}
} if (opt == -) {
ll inv = fpow(lim, P - );
for (int i = ; i < lim; i++) c[i] = c[i] * inv % P;
}
} inline poly operator * (const poly &x, const poly &y) {
poly res, u = x, v = y;
prework(u.size() + v.size() - );
ntt(u, ), ntt(v, );
for (int i = ; i < lim; i++) res.push_back(v[i] * u[i] % P);
ntt(res, -);
res.resize(u.size() + v.size() - );
return res;
} poly getInv(poly x, int len) {
x.resize(len);
if (len == ) {
poly res;
res.push_back(x[]);
return res;
}
poly y = getInv(x, (len + ) >> );
prework(len << ); poly u = x, v = y, res;
ntt(u, ), ntt(v, );
for (int i = ; i < lim; i++) res.push_back(v[i] * (2LL - u[i] * v[i] % P + P) % P);
ntt(res, -); res.resize(len);
return res;
} inline void direv(poly &c) {
for (int i = ; i < (int)c.size() - ; i++)
c[i] = c[i + ] * (i + ) % P;
c[c.size() - ] = ;
} inline void integ(poly &c) {
for (int i = (int)c.size() - ; i > ; i--)
c[i] = c[i - ] * inv[i] % P;
c[] = ;
} inline poly getLn(poly c) {
poly a = getInv(c, (int)c.size());
poly b = c;
direv(b); poly res = b * a;
res.resize(c.size());
integ(res);
return res;
} inline poly solve(int l, int r, ll *c) {
if (l == r) {
poly res;
res.push_back(), res.push_back((P - c[l]) % P);
return res;
} int mid = ((l + r) >> );
poly u = solve(l, mid, c), v = solve(mid + , r, c);
poly res = u * v;
res.resize(u.size() + v.size() - );
return res;
} inline poly mul(const poly &x, const poly &y) {
return x * y;
} } using Poly::P;
using Poly::fpow;
using Poly::inc;
using Poly::sub;
using Poly::solve;
using Poly::getLn; inline void prework() {
fac[] = inv[] = inv[] = ;
for (int i = ; i <= Maxn; i++) {
fac[i] = fac[i - ] * i % P;
if (i > ) inv[i] = (P - P / i) * inv[P % i] % P;
}
ifac[Maxn] = fpow(fac[Maxn], P - );
for (int i = Maxn - ; i >= ; i--) ifac[i] = ifac[i + ] * (i + ) % P;
} int main() {
/* #ifndef ONLINE_JUDGE
freopen("Sample.txt", "r", stdin);
#endif */ freopen("input.txt", "r", stdin);
freopen("my.out", "w", stdout); prework(); read(n), read(m);
for (int i = ; i <= n; i++) read(a[i]);
for (int i = ; i <= m; i++) read(b[i]);
read(K);
++K; poly Fa = solve(, n, a), Fb = solve(, m, b); // deb(Fa), deb(Fb); Fa.resize(K, ), Fb.resize(K, );
poly Ga = getLn(Fa), Gb = getLn(Fb); Ga.resize(K, ), Gb.resize(K, ); // deb(Ga), deb(Gb); poly A, B, C; A.push_back(n), B.push_back(m);
for (int i = ; i < K; i++) {
A.push_back((P - Ga[i]) % P * i % P * ifac[i] % P);
B.push_back((P - Gb[i]) % P * i % P * ifac[i] % P);
} // deb(A), deb(B); C = Poly::mul(A, B);
C.resize(K); // deb(C); // printf("\n");
ll invn = fpow(n, P - ), invm = fpow(m, P - );
for (int i = ; i < K; i++)
printf("%lld\n", invn * invm % P * fac[i] % P * C[i] % P); return ;
}
Luogu 4705 玩游戏的更多相关文章
- Luogu P4705 玩游戏
题目描述 Alice 和 Bob 又在玩游戏. 对于一次游戏,首先 Alice 获得一个长度为 的序列 ,Bob 获得一个长度为 的序列 bb.之后他们各从自己的序列里随机取出一个数,分别设 ...
- 【洛谷5月月赛】玩游戏(NTT,生成函数)
[洛谷5月月赛]玩游戏(NTT,生成函数) 题面 Luogu 题解 看一下要求的是什么东西 \((a_x+b_y)^i\)的期望.期望显然是所有答案和的平均数. 所以求出所有的答案就在乘一个逆元就好了 ...
- [luogu]P1070 道路游戏[DP]
[luogu]P1070 道路游戏 题目描述小新正在玩一个简单的电脑游戏.游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针 ...
- P5676 [GZOI2017]小z玩游戏【Tarjan】
小z玩游戏 Tarjan算是板子题吧,但是要稍微做一些修改,建边需要多考虑,建立"虚点". 题目描述 小 z 很无聊. 小 z 要玩游戏. 小 z 有\(N\)个新游戏,第\(i\ ...
- 原生JS实战:写了个一边玩游戏,一边记JS的API的游戏
本文是苏福的原创文章,转载请注明出处:苏福CNblog:http://www.cnblogs.com/susufufu/p/5878913.html 本程序[一边玩游戏,一边记JS的API]是本人的个 ...
- bzoj4730: Alice和Bob又在玩游戏
Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ...
- 小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和
小易邀请你玩一个数字游戏,小易给你一系列的整数.你们俩使用这些整数玩游戏.每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字. 例如: 如果{2,1,2 ...
- cdoj 1136 邱老师玩游戏 树形背包
邱老师玩游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1136 Desc ...
- win7系统玩游戏不能全屏的解决办法
1.修改注册表中的显示器的参数设置 Win键+R键,打开运行窗口,输入regedit回车,这样就打开了注册表编辑器,然后,定位到以下位置: HKEY_LOCAL_MACHINE\SYSTEM\ ...
随机推荐
- 黄聪:WordPress默认编辑器可视化切换不见了,非插件导致消失问题
1.后台---用户---我的个人资料 2.看看 [可视化编辑器]的[撰写文章时不使用可视化编辑器]项目是不是勾上了 3.去掉保存即可
- DS02--线性表
一.PTA实验作业 题目1:线性表元素的区间删除 给定一个顺序存储的线性表,请设计一个函数删除所有值大于min而且小于max的元素.删除后表中剩余元素保持顺序存储,并且相对位置不能改变. 1. 设计思 ...
- scanf在竞赛中的技巧总结ing
前言 当输入流是一个字符串,我们需要在其中提取我们所需要的数值时,我们可以在读入阶段就完成数据的筛选工作. 使用方法 scanf("%ns", str); 表示读取长度为n的字符串 ...
- appium历史版本下载地址
https://github.com/appium/appium-desktop/releases
- 网络异常时抓包操作说明tcpdump+Wireshark
转债至 https://help.aliyun.com/knowledge_detail/40564.html?spm=5176.11065259.1996646101.searchclickresu ...
- cocos2d中的坐标系统
cocos2d中Layer的默认锚点是left.buttom sprite的锚点设置 setAnchorPoint(cc.p(0.5,0.5)); 默认锚点:中心 setAnchorPoint(cc. ...
- Disconf实践指南:改造篇
上一篇文章Disconf实践指南:使用篇介绍了如何在项目中应用disconf,虽然实现了分布式配置的实时刷新,但是我们希望能够去除所有的配置文件,把配置都交给disconf管理,本地只需要实现配置监听 ...
- TreeGrid
TreeGrid是树形表格,为了展示成树形,比数据表格主要增加了以下两点: 1.表格属性中设置 idField.treeField 两个属性:idField 表示用于区分上下级的主键,treeFiel ...
- C++提高编译与链接速度的资料
1,https://blog.csdn.net/lihao21/article/details/47610309 2,https://www.zhihu.com/question/37330979 3 ...
- .net core 下的Area注册
app.UseMvc(routes => { routes.MapAreaRoute( name: "AreaRoute", areaName: "Admin&qu ...