传送门


这是两个月之前写的题,但没写博客。现在回过头来看一下发现又不会了……

还是要写博客加深记忆。


思路

显然期望可以算出总数再乘上\((nm)^{-1}\)。

那么有

\[\begin{align*}
ans_t&=\sum_{i=1}^n \sum_{j=1}^m (a_i+b_j)^t\\
&=\sum_{i=1}^n \sum_{j=1}^m \sum_{k=0}^t {t\choose k} a_i^k b_j^{t-k}\\
&=t!\sum_{k=0}^t (\sum_{i=1}^n \frac{a_i^k}{k!}) (\sum_{j=1}^m \frac{b_j^{t-k}}{(t-k)!})\\
\end {align*}
\]

显然是个卷积的形式,但怎么求\(\sum a_i^k\)呢?

这似乎是个套路。

设多项式

\[f_i(x)=\sum_{n} a_i^nx^n=\frac{1}{1-a_ix}
\]

那么所求即为

\[\sum_{i=1}^nf_i(x)=\sum_{i=1}^n \frac{1}{1-a_ix}
\]

考虑一个式子:

\[\begin{align*}
[\sum_{i=1}^n \ln(1-a_ix)]'&=\sum_{i=1}^n [\ln(1-a_ix)]'\\
&=\sum_{i=1}^n \frac{a_i}{1-a_ix}\\
&=\sum_{i=1}^n \sum_{j} a_i^{j+1}x^j\\
&=\frac{1}{x}\sum_{i=1}^n \sum_{j=1}^{\infty} a_i^jx^j\\
&=\frac 1 x \sum_{i=1}^n [f_i(x)-1]
\end{align*}
\]

好像非常好,但这东西怎么求呢?

\[g(x)=\prod_{i=1}^n (1-a_ix)
\]

则有

\[[\sum_{i=1}^n \ln(1-a_ix)]'=[\ln(\prod_{i=1}^n (1-a_ix))]'=[\ln g(x)]'
\]

显然\(g(x)\)可以分治NTT求得,然后就可以求得\(\sum f_i\),然后再NTT一下就可以得到答案了。


代码

#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define rep(i,x,y) for (register int i=(x);i<=(y);++i)
#define drep(i,x,y) for (register int i=(x);i>=(y);--i)
#define mod 998244353ll
#define sz 401010
typedef long long ll;
template<typename T>
inline void read(T& t)
{
t=0;char f=0,ch=getchar();
double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.')
{
ch=getchar();
while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();
}
t=(f?-t:t);
}
template<typename T,typename... Args>
inline void read(T& t,Args&... args){read(t); read(args...);}
void file()
{
#ifndef ONLINE_JUDGE
freopen("a.txt","r",stdin);
#endif
}
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std; ll ksm(ll x,int y)
{
ll ret=1;
for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;
return ret;
}
#define inv(x) ksm(x,mod-2) int r[sz],limit;
void NTT_init(int n)
{
limit=1;int l=-1;
while (limit<=n+n) limit<<=1,++l;
rep(i,0,limit-1) r[i]=(r[i>>1]>>1)|((i&1)<<l);
}
void NTT(ll *a,int type)
{
rep(i,0,limit-1) if (r[i]<i) swap(a[i],a[r[i]]);
for (int mid=1;mid<limit;mid<<=1)
{
ll Wn=ksm(3,(mod-1)/mid>>1);if (type==-1) Wn=inv(Wn);
for (int len=mid<<1,j=0;j<limit;j+=len)
{
ll w=1;
for (int k=0;k<mid;k++,w=w*Wn%mod)
{
ll x=a[j+k],y=a[j+k+mid]*w;
a[j+k]=(x+y)%mod;a[j+k+mid]=(mod*mod+x-y)%mod;
}
}
}
if (type==1) return;
ll I=inv(limit);
rep(i,0,limit-1) a[i]=a[i]*I%mod;
}
namespace GetLn
{
ll g[sz];
ll inv[sz];
ll a[sz],b[sz];
void work_inv(int n)// inv=g^{-1} (mod x^n)
{
if (n==1) return (void)(inv[0]=::inv(g[0]));
int mid=(n+1)>>1;
work_inv(mid);
NTT_init(n);
rep(i,0,mid-1) a[i]=inv[i];rep(i,mid,limit-1) a[i]=0;
rep(i,0,n-1) b[i]=g[i];rep(i,n,limit-1) b[i]=0;
NTT(a,1);NTT(b,1);
rep(i,0,limit-1) a[i]=a[i]*(mod+2-a[i]*b[i]%mod)%mod;
NTT(a,-1);
rep(i,0,n-1) inv[i]=a[i];
}
void work1(ll *a,int n){rep(i,0,n-2) a[i]=a[i+1]*(i+1)%mod;a[n-1]=0;}
void work2(ll *a,int n){drep(i,n,1) a[i]=a[i-1]*::inv(i)%mod;a[0]=0;}
void Ln(ll *F,int n)// F=ln F (mod x^{n+1})
{
memset(g,0,sizeof(g));memset(inv,0,sizeof(inv));
rep(i,0,n) g[i]=F[i];
work_inv(n+1);
work1(g,n);
NTT_init(n);
NTT(inv,1);NTT(g,1);
rep(i,0,limit-1) F[i]=inv[i]*g[i]%mod;
NTT(F,-1);
work2(F,n);
rep(i,n,limit-1) F[i]=0;
}
} int S[55],top;// tmp available
ll tmp[55][sz];
void solve(int l,int r,ll *ret,int *a)
{
if (l==r) return (void)(ret[0]=1,ret[1]=a[l]);
int mid=(l+r)>>1;
int ls=S[top--];solve(l,mid,tmp[ls],a);
int rs=S[top--];solve(mid+1,r,tmp[rs],a);
NTT_init(r-l+1);
NTT(tmp[ls],1);NTT(tmp[rs],1);
rep(i,0,limit-1) ret[i]=tmp[ls][i]*tmp[rs][i]%mod;
NTT(ret,-1);
S[++top]=ls;S[++top]=rs;
rep(i,0,limit-1) tmp[ls][i]=tmp[rs][i]=0;
} int n,m,T;
ll A[sz],B[sz];
int a[sz>>2],b[sz>>2];
ll fac[sz>>2],_fac[sz>>2];
void init(int n)
{
fac[0]=_fac[0]=1;
rep(i,1,n) fac[i]=fac[i-1]*i%mod;
_fac[n]=inv(fac[n]);
drep(i,n-1,1) _fac[i]=_fac[i+1]*(i+1)%mod;
} int main()
{
file();
read(n,m);
rep(i,1,n) read(a[i]);
rep(i,1,m) read(b[i]);
read(T);
init(T); rep(i,0,50) S[i]=i;top=50;solve(1,n,A,a);
GetLn::Ln(A,T+1);
rep(i,0,50) S[i]=i;top=50;solve(1,m,B,b);
GetLn::Ln(B,T+1); rep(i,1,T) A[i]=A[i]*i%mod,A[i]=(i&1)?A[i]:mod-A[i];
rep(i,1,T) B[i]=B[i]*i%mod,B[i]=(i&1)?B[i]:mod-B[i];
A[0]=n;B[0]=m; rep(i,0,T) A[i]=_fac[i]*A[i]%mod;
rep(i,0,T) B[i]=_fac[i]*B[i]%mod; NTT_init(T);
NTT(A,1);NTT(B,1);
rep(i,0,limit-1) A[i]=A[i]*B[i]%mod;
NTT(A,-1); rep(i,0,T) A[i]=A[i]*fac[i]%mod; ll I=inv(1ll*n*m%mod);
rep(i,1,T) printf("%lld\n",A[i]*I%mod);
}

洛谷P4705 玩游戏 [生成函数,NTT]的更多相关文章

  1. 洛谷 P4705 玩游戏 解题报告

    P4705 玩游戏 题意:给长为\(n\)的\(\{a_i\}\)和长为\(m\)的\(\{b_i\}\),设 \[ f(x)=\sum_{k\ge 0}\sum_{i=1}^n\sum_{j=1}^ ...

  2. 洛谷P4705 玩游戏(生成函数+多项式运算)

    题面 传送门 题解 妈呀这辣鸡题目调了我整整三天--最后发现竟然是因为分治\(NTT\)之后的多项式长度不是\(2\)的幂导致把多项式的值存下来的时候发生了一些玄学错误--玄学到了我\(WA\)的点全 ...

  3. [洛谷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 ...

  4. 洛谷 P4705 玩游戏

    题目分析 题目要求的是: \[ \sum_{i=1}^n\sum_{j=1}^m(a_i+b_j)^x(x\in [1,T]) \] 利用二项式定理化式子, \[ \begin{aligned} &a ...

  5. 【洛谷5月月赛】玩游戏(NTT,生成函数)

    [洛谷5月月赛]玩游戏(NTT,生成函数) 题面 Luogu 题解 看一下要求的是什么东西 \((a_x+b_y)^i\)的期望.期望显然是所有答案和的平均数. 所以求出所有的答案就在乘一个逆元就好了 ...

  6. 洛谷 P2197 nim游戏

    洛谷 P2197 nim游戏 题目描述 甲,乙两个人玩Nim取石子游戏. nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取 ...

  7. 洛谷 P1965 转圈游戏

    洛谷 P1965 转圈游戏 传送门 思路 每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,--,依此类推,第n − m号位置上的小伙伴走到第 0 号 ...

  8. Luogu P4705 玩游戏

    题目描述 Alice 和 Bob 又在玩游戏. 对于一次游戏,首先 Alice 获得一个长度为 ​ 的序列 ​,Bob 获得一个长度为 ​ 的序列 bb.之后他们各从自己的序列里随机取出一个数,分别设 ...

  9. 【流水调度问题】【邻项交换对比】【Johnson法则】洛谷P1080国王游戏/P1248加工生产调度/P2123皇后游戏/P1541爬山

    前提说明,因为我比较菜,关于理论性的证明大部分是搬来其他大佬的,相应地方有注明. 我自己写的部分换颜色来便于区分. 邻项交换对比是求一定条件下的最优排序的思想(个人理解).这部分最近做了一些题,就一起 ...

随机推荐

  1. Mac OSX常用工具

    换Mac有几个月了,刚换的那个月折腾了整整一个月,初用OSX很不适应,这是一种错觉,就好比说了十几年汉语,突然说英语肯定很别扭,适应后就会觉得英语更加实用. Life weiboX(http://we ...

  2. luogu P3297 [SDOI2013]逃考

    传送门 gugugu 首先每个人管理的区域是一个多边形,并且整个矩形是被这样的多边形填满的.现在的问题是求一条经过多边形最少的路径到达边界,这个可以最短路. 现在的问题是建图,显然我们应该给相邻的多边 ...

  3. dwr出现session error

    把项目冲tomcat6迁移到tomcat7之后,在项目运行中发现用到dwr的地方出现了session error错误, 网上搜了一下,是因为tomcat7的安全机制. 解决方法: 在项目的web.xm ...

  4. windows上git安装

    Git的官方网站:http://git-scm.com 1.下载:http://msysgit.github.com/ 2.安装 3.配置 用户名.邮箱 这个很重要将来项目提交的账号   $ git ...

  5. java基础_0204:运算符

    掌握Java中标识符的定义: 掌握Java中数据类型的划分以及基本数据类型的使用原则: 掌握Java运算符的使用: 掌握Java分支结构.循环结构.循环控制语法的使用: 掌握方法的定义结构以及方法重载 ...

  6. 转:Java项目开发规范参考

    Java项目开发规范参考 - KevinLee的博客 - 博客频道 - CSDN.NEThttp://blog.csdn.net/u011383131/article/details/51227860 ...

  7. Palindromic Numbers LightOJ - 1205

    题目大意: 求区间内的回文数个数 题目思路: 数位dp,先枚举前一半数字,然后填上相应的后一半数字. #include<cstdio> #include<cstring> #i ...

  8. 20165234 预备作业2 学习基础和C语言基础调查

    学习基础和C语言基础调查 一.技能学习经验及体会 你有什么技能比大多人(超过90%以上)更好? 看到这个问题,我仔细想了想,好像的确没有什么特别出众的技能,但是我想到了许多我个人的爱好. 我从小喜欢五 ...

  9. swap扩展

    没有独立的分区,本地回环设备(使用软件来模拟实现硬件) 创建一个镜像文件 https://blog.csdn.net/linuxnews/article/details/51271875 有独立的分区

  10. ROS 可视化(一): 发布PointCloud2点云数据到Rviz

    1. 相关依赖package.xml 需要添加对 pcl_ros 包的依赖 2. CMakeLists.txt find_package(PCL REQUIRED) include_directori ...