【洛谷P4705】玩游戏【二项式定理】【NTT卷积】【生成函数】【分治NTT】【函数求导】【多项式对数】
传送门
题意:给定长度为N,MN,MN,M的序列a,ba,ba,b和ttt,随机选取x∈[1,N],y∈[1,M]x \in[1,N],y\in[1,M]x∈[1,N],y∈[1,M],对于i=1,2,...,t,i =1,2,...,t,i=1,2,...,t,求(ax+by)i(a_x+b_y)^i(ax+by)i的期望
N,M,t≤100000N,M,t \leq100000N,M,t≤100000
我为什么要打这么多标签
f(k)=∑x=1n∑y=1m(ax+by)kf(k)=\sum_{x=1}^n\sum_{y=1}^m(a_x+b_y)^kf(k)=x=1∑ny=1∑m(ax+by)k
暴力拆开
f(k)=∑x=1n∑y=1m∑i=0k(ki)axibyk−if(k)=\sum_{x=1}^n\sum_{y=1}^m\sum_{i=0}^k\binom{k}{i}a_x^ib_y^{k-i}f(k)=x=1∑ny=1∑mi=0∑k(ik)axibyk−i
继续拆
f(k)=∑x=1n∑y=1m∑i=0kk!i!(k−i)!axibyk−if(k)=\sum_{x=1}^n\sum_{y=1}^m\sum_{i=0}^k\frac{k!}{i!(k-i)!}a_x^ib_y^{k-i}f(k)=x=1∑ny=1∑mi=0∑ki!(k−i)!k!axibyk−i
整理一下
f(k)k!=∑i=0k∑x=1naxii!∑y=1mbyk−i(k−i)!\frac{f(k)}{k!}=\sum_{i=0}^k\frac{\sum_{x=1}^na_x^i}{i!}\frac{\sum_{y=1}^mb_y^{k-i}}{(k-i)!}k!f(k)=i=0∑ki!∑x=1naxi(k−i)!∑y=1mbyk−i
显然是个卷积
#undef f
现在只需要求出
f(k)=∑i=1naikf(k)=\sum_{i=1}^na_i^kf(k)=i=1∑naik
右边同理
接下来是个一周目没法想到的神仙做法
对每个数单独考虑
fi(k)=aikf_i(k)=a_i^kfi(k)=aik
构造生成函数
fi(x)=1+aix+ai2x2+...f_i(x)=1+a_ix+a_i^2x^2+...fi(x)=1+aix+ai2x2+...
写成封闭形式
fi(x)=11−aixf_i(x)=\frac{1}{1-a_ix}fi(x)=1−aix1
原来是
f(x)=∑i=1n11−aixf(x)=\sum_{i=1}^n\frac{1}{1-a_ix}f(x)=i=1∑n1−aix1
加法并不好求其实很好求,分治暴力通分就可以了
考虑转成乘法做分治NTT
自然地想到算lnlnln
而这个式子和lnlnln有关的就只有倒数了
强行解释
即
ln′(1−aix)=11−aixln'(1-a_ix)=\frac{1}{1-a_ix}ln′(1−aix)=1−aix1
(上述式子的自变量是1−aix1-a_ix1−aix)
而
[ln(1−aix)]′=ln′(1−aix)(1−aix)′=−ai1−aix[ln(1-a_ix)]'=ln'(1-a_ix)(1-a_ix)'=-\frac{a_i}{1-a_ix}[ln(1−aix)]′=ln′(1−aix)(1−aix)′=−1−aixai
我们发现这玩意和fff有关系
设
gi(x)=−ai1−aixg(x)=∑i=1ngi(x)g_i(x)=-\frac{a_i}{1-a_ix}\\g(x)=\sum_{i=1}^ng_i(x)gi(x)=−1−aixaig(x)=i=1∑ngi(x)
有
fi(x)=1−xgi(x)f_i(x)=1-xg_i(x)fi(x)=1−xgi(x)
所以
f(x)=n−xg(x)f(x)=n-xg(x)f(x)=n−xg(x)
现在只需要求出ggg
继续推之前的式子
g(x)=∑i=1n−ai1−aixg(x)=\sum_{i=1}^n-\frac{a_i}{1-a_ix}g(x)=i=1∑n−1−aixai
=∑i=1n[ln(1−aix)]′=\sum_{i=1}^n[ln(1-a_ix)]'=i=1∑n[ln(1−aix)]′
脑补一下,导数是可加的
g(x)=[∑i=1nln(1−aix)]′g(x)=[\sum_{i=1}^nln(1-a_ix)]'g(x)=[i=1∑nln(1−aix)]′
拆进去
g(x)=[ln∏i=1n(1−aix)]′g(x)=[ln\prod_{i=1}^n(1-a_ix)]'g(x)=[lni=1∏n(1−aix)]′
分治NTT即可
复杂度O(nlog2n)O(nlog^2n)O(nlog2n)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#define MAXN 262144+5
using namespace std;
const int MOD=998244353;
typedef long long ll;
int fac[MAXN],finv[MAXN];
inline int add(const int& x,const int& y){return x+y>=MOD? x+y-MOD:x+y;}
inline int dec(const int& x,const int& y){return x<y? x-y+MOD:x-y;}
inline int qpow(int a,int p)
{int ans=1;while (p){if (p&1) ans=(ll)ans*a%MOD;a=(ll)a*a%MOD;p>>=1;}return ans;
}
#define inv(x) qpow(x,MOD-2)
int r[MAXN],rt[2][MAXN];
inline void init(const int& l){for (int i=0;i<(1<<l);i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));}
void NTT(int* a,int l,int type)
{int lim=1<<l;for (int i=0;i<lim;i++) if (i<r[i]) swap(a[i],a[r[i]]);for (int L=0;L<l;L++){int mid=1<<L,len=mid<<1;int Wn=rt[type][L+1];for (int s=0;s<lim;s+=len)for (int k=0,w=1;k<mid;k++,w=(ll)w*Wn%MOD){int x=a[s+k],y=(ll)w*a[s+mid+k]%MOD;a[s+k]=add(x,y);a[s+mid+k]=dec(x,y);}}if (type){int t=inv(lim);for (int i=0;i<lim;i++) a[i]=(ll)a[i]*t%MOD;}
}
void getinv(int* A,int* B,int n)
{static int t[MAXN];if (n==1) return (void)(*B=inv(*A));getinv(A,B,(n+1)>>1);int l=0;while ((1<<l)<(n<<1)) ++l;for (int i=0;i<n;i++) t[i]=A[i];for (int i=n;i<(1<<l);i++) t[i]=B[i]=0;init(l);NTT(t,l,0);NTT(B,l,0);for (int i=0;i<(1<<l);i++) B[i]=(ll)B[i]*(MOD+2-(ll)t[i]*B[i]%MOD)%MOD;NTT(B,l,1);for (int i=n;i<(1<<l);i++) B[i]=0;
}
inline void deriv(int* A,int* B,int n)
{for (int i=0;i<n-1;i++) B[i]=(ll)A[i+1]*(i+1)%MOD;B[n-1]=0;
}
inline void integ(int* A,int* B,int n)
{for (int i=1;i<n;i++) B[i]=(ll)A[i-1]*finv[i]%MOD*fac[i-1]%MOD;B[0]=0;
}
void getln(int* A,int* B,int n)
{static int f[MAXN],g[MAXN];deriv(A,f,n);getinv(A,g,n);int l=0;while ((1<<l)<(n<<1)) ++l;init(l);for (int i=n;i<(1<<l);i++) f[i]=g[i]=0;NTT(f,l,0);NTT(g,l,0);for (int i=0;i<(1<<l);i++) f[i]=(ll)f[i]*g[i]%MOD;NTT(f,l,1);integ(f,B,n);
}
void solve(int* a,int* f,int l,int r)
{if (l==r){f[0]=1;f[1]=MOD-a[l];return;}int mid=(l+r)>>1;int len=0;while ((1<<len)<=r-l+1) ++len;int L[(1<<len)+5],R[(1<<len)+5];memset(L,0,sizeof(L));memset(R,0,sizeof(R));solve(a,L,l,mid);solve(a,R,mid+1,r);init(len);NTT(L,len,0);NTT(R,len,0);for (int i=0;i<(1<<len);i++) f[i]=(ll)L[i]*R[i]%MOD;NTT(f,len,1);
}
int a[MAXN],b[MAXN];
int f[MAXN],g[MAXN];
int A[MAXN],B[MAXN];
int main()
{rt[0][23]=qpow(3,119);rt[1][23]=inv(rt[0][23]);for (int i=22;i>=0;i--){rt[0][i]=(ll)rt[0][i+1]*rt[0][i+1]%MOD;rt[1][i]=(ll)rt[1][i+1]*rt[1][i+1]%MOD;}int n,m;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]);int t;scanf("%d",&t);fac[0]=1;for (int i=1;i<=t;i++) fac[i]=(ll)fac[i-1]*i%MOD;finv[t]=inv(fac[t]);for (int i=t-1;i>=0;i--) finv[i]=(ll)finv[i+1]*(i+1)%MOD;solve(a,g,1,n);getln(g,f,t+1);deriv(f,g,t+1);for (int i=1;i<=t;i++) A[i]=MOD-g[i-1];A[0]=n;memset(f,0,sizeof(f));memset(g,0,sizeof(g));solve(b,g,1,m);getln(g,f,t+1);deriv(f,g,t+1);for (int i=1;i<=t;i++) B[i]=MOD-g[i-1];B[0]=m;
// for (int i=0;i<=t;i++) printf("%d%c",A[i]," \n"[i==t]);
// for (int i=0;i<=t;i++)
// {// int sum=0;
// for (int k=1;k<=n;k++) sum=add(sum,qpow(a[k],i));
// printf("%d%c",sum," \n"[i==t]);
// }
// for (int i=0;i<=t;i++) printf("%d%c",B[i]," \n"[i==t]);
// for (int i=0;i<=t;i++)
// {// int sum=0;
// for (int k=1;k<=m;k++) sum=add(sum,qpow(b[k],i));
// printf("%d%c",sum," \n"[i==t]);
// } for (int i=0;i<=t;i++){A[i]=(ll)A[i]*finv[i]%MOD;B[i]=(ll)B[i]*finv[i]%MOD;}int l=0;while ((1<<l)<=(t<<1)) ++l;init(l);NTT(A,l,0);NTT(B,l,0);for (int i=0;i<(1<<l);i++) A[i]=(ll)A[i]*B[i]%MOD;NTT(A,l,1);for (int i=1;i<=t;i++) A[i]=(ll)A[i]*fac[i]%MOD;int tmp=(ll)inv(n)*inv(m)%MOD;for (int i=1;i<=t;i++) printf("%d\n",(ll)A[i]*tmp%MOD);return 0;
}
【洛谷P4705】玩游戏【二项式定理】【NTT卷积】【生成函数】【分治NTT】【函数求导】【多项式对数】相关推荐
- 洛谷P4705 玩游戏(生成函数+多项式运算)
题面 传送门 题解 妈呀这辣鸡题目调了我整整三天--最后发现竟然是因为分治\(NTT\)之后的多项式长度不是\(2\)的幂导致把多项式的值存下来的时候发生了一些玄学错误--玄学到了我\(WA\)的点全 ...
- [洛谷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\l ...
- P4705 玩游戏(生成函数,多项式ln)
P4705 玩游戏 有ansk=∑i=1n∑j=1m(ai+bj)knm先舍弃nm不管ansk=∑r=0k∑i=1n∑j=1mCkrairbjk−r=∑r=0k∑i=1n∑j=1mk!r!(k−r)! ...
- 洛谷 P2197 nim游戏
洛谷 P2197 nim游戏 题目描述 甲,乙两个人玩Nim取石子游戏. nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取 ...
- 洛谷 P1129 矩阵游戏
洛谷 P1129 矩阵游戏 题目链接 题目描述 小 Q 是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个 n×n 黑白方阵进行(如同国际象棋一般,只是颜色是 ...
- 洛谷 P3041 视频游戏的连击Video Game Combos(AC自动机+拓扑排序+数位DP)
洛谷 P3041 视频游戏的连击Video Game Combos 难度一般,不过这个数位DP其实应该叫做记忆化搜索 题意:玩游戏时可以通过按键组合打出combo技能:然后是已知N个combo的按键方 ...
- 洛谷 P1558 色板游戏
传送门:洛谷 P1558 色板游戏 算法分析:观察到数据范围:\(1\leq T\leq 30\) ,考虑使用二进制来进行状态压缩 将颜色\(x\)表示为 \(1<<(x-1)\) 即 \ ...
- 动态规划——洛谷_P1057传球游戏
题目: 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏.游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球, ...
- 洛谷——P1000 超级玛丽游戏
P1000 超级玛丽游戏 题目背景 本题是洛谷的试机题目,可以帮助了解洛谷的使用. 建议完成本题目后继续尝试P1001.P1008. 另外强烈推荐新用户必读贴 题目描述 超级玛丽是一个非常经典的游戏. ...
最新文章
- 网络营销十技之六:联署计划营销
- cytoscape---插件clueGO的使用
- 语音识别、传统语音识别、带权有限转态转换器、深度语音识别、时序分类、CTC解码
- Day 03 为什么大学生难管理时间
- mount -t 挂载指定的文件格式
- Android学习笔记-----一个很好用的搜索网站,你懂的
- afe模拟前端的重要性_UCD3138模拟前端(AFE)模块:模拟前端模块(AFE)简介
- 【转】1.9 Asp.Net Core 轻松学-多线程之取消令牌(
- Latex+Texstudio+Texlive 2020 windows10 安装教程
- Rust 编程有什么好?
- 数据结构与算法之树的遍历
- 音视频学习系列第(四)篇---视频的采集预览
- win7 64BIT下使用VC2005的问题
- Qt调用工业相机之海康威视相机
- 程序员如何做好应聘?简历、面试和Offer
- 核方法 Kernel method
- Linux动态库依赖其它动态库的问题
- 10被动语态,双重所有格
- java 量化指标_SAR指标配合阶段高低价的量化交易策略
- go 学习笔记之咬文嚼字带你弄清楚 defer 延迟函数
热门文章
- 我妈要把闺蜜介绍给我当女朋友......
- 女朋友掉水里,各类程序猿怎么救?
- 备受期待的Python深度学习来了
- mysql映射超_Hibernate的映射类型 hibernate mysql映射类型
- 腐蚀rust服务器命令_RUST++ MOD
- linux+awk忽略tab符号,awk 如何避免文本中出现特殊符号的影响?
- 中断原理在计算机中的应用,最新 计算机原理与应用 复习3-判断题
- jsp后台批量导入excel表格数据到mysql中_PHP批量导入excell表格到mysql数据库
- 几何画板自定义工具_几何画板最强版 v5.06 中文版(含教程/实例/控件/打包机/工具集)...
- C++ 学习之旅(7)——指针pointer