题解 P4705 【玩游戏】
这题是真的神仙啊...居然用的 stl 来卡常?
话说 998244353 真的可以一眼 NTT ?
noteskey
所以说只要推柿子就好了但是有的地方的推导根本就想不到...
我们令第 t 个答案为 \(ANS_t\over nm\) ,除去 nm 其实就是算期望时要除去的方案数
那么有:
\]
那么我们发现这个东西就是卷积的形式了,于是我们的任务就是快速算出后面两个表达式所对应的的多项式
我们设:
\]
那么我们只要求出 \(f(1...t) ,g(1...t)\) 即可
但是求出来没有这么简单...
我们考虑先求出:
\]
然后我们令:
\]
那么 \(F(x)\) 的第 k 项就表示了
\]
即:
\]
那么我们现在发现要求出 \(f_{j=1...n}(x)\) ,但是没有什么高效的办法能解决这个问题
于是我们把 \(f_{j}(x)\) 中的上限 k 改掉,变成 \(\infty\) ,这样我们就能用生成函数来解决了:
\]
然后就是把这些 \(f_j(x)\) 加起来了:
\]
最后就是怎么合并这些 \(f_j(x)\) 的问题了,我们发现:
\]
发现这个东西和我们要求的东西蛮像的,那么这里又有:
\]
那么我们的任务就已经是求出 G(x) 了
\]
然后我们就要在优秀的时间内求出\(\prod_{i=1}^n (1-a_ix)\) ,然后取个 Ln 再求个 Inv ,右移一位让最低项为 n , \(F(x)\) 就构造好了
至于对 b 数组也是同样的求法,两个要求的多项式求出来后,我们还要让两个多项式除去对应的阶乘,然后再去卷积
卷完积后也和最开始的式子一样,第 t 项乘上 t! ,然后别忘了我们还要除去 nm 才是最终的答案...
最后就是顺序输出就好了
code
这没救了的压行【雾
//by Judge
#include<bits/stdc++.h>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
#define ll long long
using namespace std;
const int mod=998244353;
const int iG=332748118;
const int M=524288+3;
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline int inc(int x,int y){return (x+y)%mod;}
inline int mul(int x,int y){return 1ll*x*y%mod;}
inline int dec(int x,int y){return (x-y+mod)%mod;}
inline int read(){ int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(int x,char chr='\n'){
if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int n,m,t,qq,rev,d,limit;
arr a,b,f,g,fac,ifac,lg,r[20],D[21],G[2];
inline int qpow(Rg int x,Rg int p=mod-2,Rg int s=1){
for(;p;p>>=1,x=mul(x,x)) if(p&1) s=mul(s,x); return s;
}
inline void prep(int n=262143){ for(limit=1;limit<=n;limit<<=1);
fac[0]=fac[1]=1; fp(i,2,limit) fac[i]=mul(fac[i-1],i);
fp(d,1,19){ lg[1<<d]=d; fp(i,0,(1<<d)-1)
r[d][i]=(r[d][i>>1]>>1)|((i&1)<<(d-1));
}
for(Rg int t=(mod-1)>>1,i=1,x,y;i<limit;i<<=1,t>>=1){
x=qpow(3,t),y=qpow(iG,t),G[0][i]=G[1][i]=1;
fp(k,1,i-1) G[1][i+k]=mul(G[1][i+k-1],x);
fp(k,1,i-1) G[0][i+k]=mul(G[0][i+k-1],y);
}
}
inline void init(int n){
for(limit=1;limit<n;limit<<=1); d=lg[limit];
}
inline void NTT(int* a,int tp){
fp(i,0,limit-1) if(i<r[d][i]) swap(a[i],a[r[d][i]]);
for(Rg int mid=1,I=2;mid<limit;mid<<=1,I<<=1)
for(Rg int j=0,x,y;j<limit;j+=I) fp(k,0,mid-1)
x=a[j+k],y=mul(a[j+k+mid],G[tp][mid+k]),
a[j+k]=inc(x,y),a[j+k+mid]=dec(x,y);
if(tp) return ; int inv=qpow(limit);
fp(i,0,limit-1) a[i]=mul(a[i],inv);
}
inline void Mul(int* a,int* b,int* c,int n){
static arr A,B; fp(i,0,n-1) A[i]=a[i],B[i]=b[i];
fill(A+n,A+limit,0),fill(B+n,B+limit,0),NTT(A,1),NTT(B,1);
fp(i,0,limit-1) A[i]=mul(A[i],B[i]); NTT(A,0),copy(A,A+limit,c);
}
void Inv(int* a,int* b,int n){
if(n==1) return b[0]=qpow(a[0]),void();
Inv(a,b,n>>1),init(n<<1); static arr c,d;
fp(i,0,n-1) c[i]=a[i],d[i]=b[i];
fp(i,n,limit-1) c[i]=d[i]=0; NTT(c,1),NTT(d,1);
fp(i,0,limit-1) c[i]=mul(c[i],mul(d[i],d[i])); NTT(c,0);
fp(i,0,n-1) b[i]=dec(inc(b[i],b[i]),c[i]);
}
inline void Derv(int* a,int* b,int n){
fp(i,1,n-1) b[i-1]=mul(a[i],i); b[n-1]=0;
}
inline void Ln(int* a,int* b,int n){ static arr c,d;
memset(c,0,(n+1)<<2),memset(d,0,(n+1)<<2);
Derv(a,c,n),Inv(a,d,n),init(n<<1);
Mul(c,d,b,n),fill(b+n,b+limit,0);
}
inline void solv(int* a,int d,int l,int r){
if(l==r) return D[d][0]=1,D[d][1]=mod-a[l],void(); static arr A,B;
int mid=(l+r)>>1; solv(a,d,l,mid),solv(a,d+1,mid+1,r),init(r-l+2);
fp(i,0,mid-l+1) A[i]=D[d][i]; fp(i,0,r-mid) B[i]=D[d+1][i];
fill(A+mid-l+2,A+limit,0),fill(B+r-mid+1,B+limit,0);
Mul(A,B,D[d],r-l+1),fill(D[d]+r-l+2,D[d]+limit,0);
}
int main(){ n=read(),m=read(),rev=qpow(mul(n,m)),prep();
fp(i,1,n) a[i]=read(); fp(i,1,m) b[i]=read();
solv(a,1,1,n),copy(D[1],D[1]+n+1,f);
solv(b,1,1,m),copy(D[1],D[1]+m+1,g);
t=read(),qq=max(max(n,m),t); init(qq+1),qq=limit;
Ln(f,f+1,qq),Ln(g,g+1,qq),f[0]=n,g[0]=m;
fp(i,1,qq-1) f[i]=dec(mod,f[i]),g[i]=dec(mod,g[i]);
fac[0]=ifac[0]=ifac[1]=1; fp(i,1,qq-1) fac[i]=mul(fac[i-1],i);
fp(i,2,qq-1) ifac[i]=mul(mod-mod/i,ifac[mod%i]);
fp(i,1,qq-1) ifac[i]=mul(ifac[i],ifac[i-1]);
fp(i,0,qq-1) f[i]=mul(f[i],ifac[i]),g[i]=mul(g[i],ifac[i]);
fp(i,qq,qq<<1) f[i]=g[i]=0; init(qq<<1),NTT(f,1),NTT(g,1);
fp(i,0,limit-1) f[i]=mul(f[i],g[i]); NTT(f,0);
fp(i,1,t) print(mul(f[i],mul(fac[i],rev))); return Ot(),0;
}
题解 P4705 【玩游戏】的更多相关文章
- 洛谷 P4705 玩游戏 解题报告
P4705 玩游戏 题意:给长为\(n\)的\(\{a_i\}\)和长为\(m\)的\(\{b_i\}\),设 \[ f(x)=\sum_{k\ge 0}\sum_{i=1}^n\sum_{j=1}^ ...
- Luogu P4705 玩游戏
题目描述 Alice 和 Bob 又在玩游戏. 对于一次游戏,首先 Alice 获得一个长度为 的序列 ,Bob 获得一个长度为 的序列 bb.之后他们各从自己的序列里随机取出一个数,分别设 ...
- [洛谷P4705]玩游戏
题目大意:对于每个$k\in[1,t]$,求:$$\dfrac{\sum\limits_{i=1}^n\sum\limits_{j=1}^m(a_i+b_j)^k}{nm}$$$n,m,t\leqsl ...
- 洛谷P4705 玩游戏(生成函数+多项式运算)
题面 传送门 题解 妈呀这辣鸡题目调了我整整三天--最后发现竟然是因为分治\(NTT\)之后的多项式长度不是\(2\)的幂导致把多项式的值存下来的时候发生了一些玄学错误--玄学到了我\(WA\)的点全 ...
- P4705 玩游戏
思路 超级麻烦... 写了一堆最后常数太大T飞了... 真的难受 发现solve函数可以不用把下一层复制上来,直接传指针就可以,下次再说写不写叭 思路 \[ ans_k=\sum_{i=1}^n\su ...
- 洛谷P4705 玩游戏 [生成函数,NTT]
传送门 这是两个月之前写的题,但没写博客.现在回过头来看一下发现又不会了-- 还是要写博客加深记忆. 思路 显然期望可以算出总数再乘上\((nm)^{-1}\). 那么有 \[ \begin{alig ...
- 洛谷 P4705 玩游戏
题目分析 题目要求的是: \[ \sum_{i=1}^n\sum_{j=1}^m(a_i+b_j)^x(x\in [1,T]) \] 利用二项式定理化式子, \[ \begin{aligned} &a ...
- 【题解】P5589 小猪佩奇玩游戏(期望)
[题解]P5589 小猪佩奇玩游戏(期望) 假设一个点有\(x\)个点(包括自己)可以到达他,他就对答案有\(1/x\)的贡献.这是因为这个点必须被删掉而通过删掉这个点本身删掉这个点的概率是\(1/x ...
- cdoj 1136 邱老师玩游戏 树形背包
邱老师玩游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1136 Desc ...
- 【洛谷5月月赛】玩游戏(NTT,生成函数)
[洛谷5月月赛]玩游戏(NTT,生成函数) 题面 Luogu 题解 看一下要求的是什么东西 \((a_x+b_y)^i\)的期望.期望显然是所有答案和的平均数. 所以求出所有的答案就在乘一个逆元就好了 ...
随机推荐
- AppiumDesktop录制脚本
AppiumDesktop启动页面: 启动AppiumDesktop以后点击该页面右上角的Start New Session按钮,就会启动一个新的会话窗口(如下图),在这个窗口我们需要配置一些Desi ...
- Commons-DbUtils
<dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils& ...
- centos7之openvpn搭建
一.环境介绍 操作系统centos7.4 openvpn版本:openvpn-2.1 lzo版本:lzo-2.03 二.搭建 关闭firewalld防火墙,并设置开机不启动.关闭selinux sys ...
- memcache+tp3.2实现消息队列
){)){ ){));} $this->unLock();$this->resetSide('A');$this->resetSide('B');return true;} /* * ...
- 想玩 Android 开发板?这些常用命令你不知不行!
2019-04-19 关键字:Android机顶盒常用命令.Linux命令 笔者早年间从事 Android 机顶盒开发工作,那会刚毕业,技术也比较菜,工作过程中遇到过不少困难,不过所幸当时就有做笔记的 ...
- BZOJ3236[Ahoi2013]作业——莫队+树状数组/莫队+分块
题目描述 输入 输出 样例输入 3 4 1 2 2 1 2 1 3 1 2 1 1 1 3 1 3 2 3 2 3 样例输出 2 2 1 1 3 2 2 1 提示 N=100000,M=1000000 ...
- JetBrain系列IDE提示Filesystem Case-Sensitivity Mismatch的解决
目录 解决方法 1. 用文本编辑器修改APP包文件中的属性文件(不推荐) 2. 复制或新建属性文件到APP的启动目录,添加对应的属性项(推荐) 解决方法1 1. 用文本编辑器修改APP包文件中的属性文 ...
- 洛谷P3327 约数个数和 结论+莫比乌斯反演
原题 就是让你求\(\sum\limits_{i=1}\sum\limits_{j=1}d(ij)\)(其中\(d(x)\)表示\(x\)的因数个数) 首先有引理(然而并没有证明): \(d(ij)= ...
- linux下实用的快速随机生成复杂密码
linux下实用的快速随机生成复杂密码 [root@test.db-audit.1 ~]# </dev/urandom tr -dc '1234567890!@#$%abcdefghigklmn ...
- Unity Technologies-提供全面的技术支持服务
Unity Technologies-提供全面的技术支持服务 在收费服务是由Unity大华区面向研发企业推出的一项技术支持服务,以全中文的方式进行,为研发团队解答在使用Unity引擎过程中遇到的各类问 ...