ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多项式与生成函数学习笔记

2020-10-11 20:04:13  阅读:282  来源: 互联网

标签:frac 函数 ln int 多项式 笔记 pmod 2n equiv


目录

多项式与生成函数学习笔记

多项式

求导

只有我傻傻不会求导,所以放几个常见导数。

\[C'=0(\text{C为常数}) \]

\[(x^n)'=nx^{n-1} \]

\[(\sin x)'=\cos x \]

\[(\cos x)'=-\sin x \]

\[(e^x)'=e^x \]

\[(a^x)'=a^x\ln a \]

\[(\ln x)'=\frac{1}{x} \]

\[(\log_a x)'=\frac{1}{x\ln a} \]

链式法则:

\[(f(g(x)))'=f'(g(x))g'(x) \]

泰勒展开

把 \(F(x)\) 在 \(F(x_0)\) 处泰勒展开:

\[F(x)=F(x_0)+F'(x_0)(x-x_0)+\frac{F''(x_0)}{2}(x-x_0)^2\cdots+\frac{F^{(n)}(x_0)}{n!}(x-x_0)^n+\cdots \]

牛顿迭代

给定函数 \(G\) ,找出多项式 \(F(x)\) 使得:

\[G(F(x))\equiv 0 \pmod{x^n} \]

考虑倍增,已知 \(G(F_n(x))\equiv 0 \pmod{x^n}\) ,求 \(F_{2n}(x)\) 满足 \(G(F_{2n}(x))\equiv 0\pmod{x^{2n}}\) 。

\[F_n(x)\equiv F_{2n}(x) \pmod {x^n} \]

\[(F_{2n}(x)-F_{n}(x))^2\equiv 0 \pmod{x^{2n}} \]

把 \(G(F_{2n}(x))\) 在 \(G(F_{n}(x))\) 处做泰勒展开:

\[G(F_{2n}(x))=G(F_{n}(x))+G'(F_{n}(x))(F_{2n}(x)-F_{n}(x))+\frac{G''(F_{n}(x))}{2}(F_{2n}(x)-F_{n}(x))^2+\cdots \]

后面的项和左边的项在 \(\pmod {x^{2n}}\) 意义下都是 \(0\) :

\[0\equiv G(F_{n}(x))+G'(F_{n}(x))(F_{2n}(x)-F_{n}(x)) \pmod{x^{2n}} \]

\[F_{2n}(x)\equiv F_n(x)-\frac{G(F_n(x))}{G'(F_n(x))} \pmod{x^{2n}} \]

多项式求逆

给定 \(F(x)\) ,求出 \(P(x)\) 满足 \(F(x)P(x)\equiv 1 \pmod {x^n}\) 。

考虑倍增,设 \(F_n(x)P(x)\equiv 1\pmod{x^n}\) ,那么:

\[F_{2n}(x)\equiv F_n(x) \pmod {x^n} \]

\[(F_{2n}(x)-F_n(x))^2\equiv 0 \pmod{x^{2n}} \]

\[(F_{2n}^2(x)+F_n^2(x)-2F_{2n}(x)F_n(x))P(x)\equiv 0 \pmod{x^{2n}} \]

\[F_{2n}(x)\equiv F_n(x)(2-F_n(x)P(x)) \pmod {x^{2n}} \]

时间复杂度: \(\mathcal O(n\log_2n)\) 。

多项式除法

给定 \(A(x),B(x)\) ,求 \(D(x),R(x)\) 满足 \(A(x)=D(x)B(x)+R(x)\) 并且 \(\deg(R(x))<\deg(B(x))\) 。

设 \(\deg(A(x))=n,\deg(B(x))=m\) ,则 \(\deg(D(x))=n-m,\deg(R(x))<m\) ,不妨设 \(\deg(R(x))=m-1\) 。

记 \(F^R(x)=x^{\deg(F(x))}F(\frac{1}{x})\) ,也就是将 \(F\) 的系数反转得到的多项式。

原式也可以写成:

\[A(\frac{1}{x})=D(\frac{1}{x})B(\frac{1}{x})+R(\frac{1}{x}) \]

\[(x^nA(\frac{1}{x}))=(x^{n-m}D(\frac{1}{x}))(x^mB(\frac{1}{x}))+x^{n-m+1}(x^{m-1}R(\frac{1}{x})) \]

\[A^R(x)=D^R(x)B^R(x)+x^{n-m+1}R^R(x) \]

\[A^R(x)\equiv D^R(x)B^R(x)\pmod{x^{n-m+1}} \]

因为 \(\deg(D(x))=n-m<n-m+1\) ,所以求出来的 \(D(x)\) 是真实的,由此可以求出 \(R(x)\) 。

时间复杂度: \(\mathcal O(n\log_2n)\) 。

多项式 ln

给定 \(F(x)\) ,求出 \(P(x)\) 满足 \(P(x)\equiv \ln(F(x))\pmod{x^n}\) 。

两边同时求导:

\[P'(x)\equiv (\ln(F(x)))'\equiv \frac{1}{F(x)}F'(x)\pmod {x^n} \]

\[P(x)\equiv \int \frac{F'(x)}{F(x)} \pmod{x^n} \]

\(P(x)\) 常数项为 \(0\) , \(F(x)\) 常数项为 \(1\) 。(不为 \(1\) 不收敛)

时间复杂度: \(\mathcal O(n\log_2 n)\) 。

多项式 exp

给定 \(F(x)\) ,求出 \(P(x)\) 满足 \(P(x)\equiv e^{F(x)}\pmod{x^n}\) 。

\[\ln(P(x))-F(x)\equiv 0\pmod{x^n} \]

套牛顿迭代, \(G(X)=\ln X-F(x)\) 。

\[P_{2n}(x)\equiv P_n(x)-\frac{G(P_n(x))}{G'(P_n(x))}\equiv P_n(x)-(\ln(P_n(x))-F(x))P_n(x) \pmod{x^{2n}} \]

\(F(x)\) 常数项为 \(0\) , \(P(x)\) 常数项为 \(1\) 。

时间复杂度: \(\mathcal O(n\log_2n)\) 。

多项式快速幂

给定 \(F(x)\) ,求出 \(P(x)\) 满足 \(P(x)\equiv F^m(x) \pmod{x^n}\) 。

两边同时取 \(\ln\) :

\[\ln P(x)\equiv \ln F^m(x)\equiv m\ln F(x) \pmod{x^n} \]

\[P(x)\equiv e^{m\ln F(x)} \pmod{x^n} \]

先多项式取 \(\ln\) ,再乘上 \(m\) ,再 \(\exp\) 回去就行了,需要注意的就是在执行 \(\ln\) 操作时要求 \(F(x)\) 常数项为 \(1\) ,所以先给 \(F(x)\) 除上其常数项的值再进行后面操作,最后再乘上其常数项值的 \(m\) 次方即可还原回去;如果常数项为 \(0\) ,就先把 \(0\) 丢掉(整体除以 \(x\) ),到最后面再加上去(整体乘以 \(x^m\) )即可。

时间复杂度: \(\mathcal O(n\log_2n)\) 。

多项式多点求值

不会,这个考场上考了就随它去吧。

多项式多点插值

不会,这个考场上考了就随它去吧。

生成函数

形式幂级数

这里可能不太严谨,不过能理解就行了。

对于形式幂级数 \(F(x)=\sum_{i=0}^{\infty}a_ix^i\) ,其中我们并不关心 \(x\) 的数值,且对收敛和发散的问题不感兴趣,只对系数序列 \(\{a\}\) 感兴趣,只关心 \(\{a\}\) 的值;当数列 \(\{a\}\) 有限的时候,也就是存在 \(t\) ,满足 \(a_i(i\ge t)=0\) ,那么 \(F(x)\) 也可以称为形式多项式。

比如我们就可以认为 \(\sum_{i=0}^{\infty}x^i=\frac{1}{1-x}\) ,当然这个式子在 \(x\ge 1\) 是不成立,但是我们并不关心 \(x\) 的具体取值,所以就可以默认 \(0<x<1\) ,然后这样认为。

生成函数就是形式幂级数。

形式幂级数的运算

设 \(A(x)=\sum_{i=0}^{\infty}a_ix^i,B(x)=\sum_{i=0}^{\infty}b_ix^i\) ,有:

\[A(x)+B(x)=\sum_{i=0}^{\infty}(a_i+b_i)x^i \]

\[A(x)\times B(x)=\sum_{i=0}^{\infty}x^i\sum_{j+k=i}a_jb_k \]

乘积就是乘法卷积。

普通型生成函数

序列 \(\{a\}\) 的普通型生成函数为:

\[F(x)=\sum_{i=0}^{\infty}a_ix^i \]

可以用来解决数列递推等问题。

指数型生成函数

序列 \(\{a\}\) 的指数型生成函数为:

\[F(x)=\sum_{i=0}^{\infty}\frac{a_i}{i!}x^i \]

可以用来解决组合排列等问题。

题目

为了假装自己学了生成函数和多项式,在这里放两道题目来分析一下。

洛谷P5860 「SWTR-03」Counting Trees

题意简述

给定长度为 \(n\) 的序列 \(v_i\) ,询问 \(\{v\}\) 中有多少子序列满足分别以子序列中的数作为度数的树存在。

\(2\le n\le 5\times 10^5,1\le v_i\le n\) 。

题目分析

设选出来了一个长度为 \(m\) 的子序列 \(\{a\}\) ,那么需要满足 \(\sum_{i=1}^ma_i=2(m-1)\) ,即 \(\sum_{i=1}^m(a_i-2)=-2\) ,由此我们可以得出,答案就是 \([x^{-2}]\prod_{i=1}^n(x^{v_i-2}+1)\) 。

但是我们没有办法处理 \(x\) 的指数为负的情况,考虑到当 \(v_i=1\) 时, \(x^{v_i-2}+1=\frac{1}{x}+1\) ,可以乘以 \(x\) 使得指数变成正数,当然前面的 \(x^{-2}\) 也要相应地乘以 \(x\) 。

如何求 \(\prod_{i=1}^n(x^{t_i}+1)\) ?这个和用多项式优化背包时一样的,设 \(F_t(x)=x^{t}+1\) ,那么要求的就是 \(\prod_{i=1}^nF_{t_i}(x)=e^{\sum_{i=1}^n\ln(F_{t_i}(x))}\) ,于是如果知道了 \(\ln(F_t(x))\) ,就可以先算和,最后只需要一次 \(\exp()\) 就可以还原回去了。

如何算 \(\ln(F_t(x))=\ln(x^t+1)\) ?设 \(G(x)=\ln(x^t+1)\) ,那么两边同时求导:

\[G'(x)=\frac{tx^{t-1}}{x^t+1} \]

\[=tx^{t-1}\sum_{i=0}^{\infty}(-x^t)^i \]

\[=tx^{t-1}\sum_{i=1}^{\infty}(-1)^{i-1}x^{ti-t} \]

\[=\sum_{i=1}^{\infty}(-1)^{i-1}tx^{ti-1} \]

\[G(x)=\int \sum_{i=1}^{\infty}(-1)^{i-1}tx^{ti-1} \]

\[=\sum_{i=1}^{\infty}\frac{(-1)^{i-1}}{i}x^{ti} \]

对于每个 \(t\) 统计 \(F_t(x)\) 的出现次数然后最后再加起来即可做到 \(n\log_2n\) 。

需要注意的一点就是当 \(v_i=2\) 时 , \(x^{v_i-2}+1=2\) ,需要特殊处理,在 \(\exp()\) 之前先不要乘起来,最后算答案的时候再乘起来。

参考代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ch() getchar()
#define pc(x) putchar(x)
using namespace std;
template<typename T>void read(T&x){
	char c;int f;
	for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
	for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
}
template<typename T>void write(T x){
	static char q[64];int cnt=0;
	if(x==0)return pc('0'),void();
	if(x<0)pc('-'),x=-x;
	while(x)q[cnt++]=x%10,x/=10;
	while(cnt--)pc(q[cnt]+'0');
}
const int maxn=800005,mod=998244353;
int mo(const int x){
	return x>=mod?x-mod:x;
}
int power(int a,int x){
	int re=1;
	while(x){
		if(x&1)re=1ll*re*a%mod;
		a=1ll*a*a%mod,x>>=1;
	}
	return re;
}
namespace polynomial{
	int power(int a,int x){
		int re=1;
		while(x){
			if(x&1)re=1ll*re*a%mod;
			a=1ll*a*a%mod,x>>=1;
		}
		return re;
	}
	const int g_=3;
	int rev[maxn];
	void initNTT(int m,int&n){
		n=1;int cn=-1;
		while(n<m)n<<=1,++cn;
		for(int i=1;i<n;++i)
			rev[i]=(rev[i>>1]>>1)|((i&1)<<cn);
	}
	void NTT(int*F,int n,int rv){
		for(int i=0;i<n;++i)if(rev[i]<i)
			F[i]^=F[rev[i]]^=F[i]^=F[rev[i]];
		for(int mid=1;mid<n;mid<<=1){
			const int len=mid<<1,gn=power(g_,(mod-1)/len);
			for(int i=0;i<n;i+=len){
				for(int j=0,g=1;j<mid;++j,g=1ll*g*gn%mod){
					int l=i+j,r=l+mid;
					int L=F[l],R=1ll*F[r]*g%mod;
					F[l]=mo(L+R),F[r]=mo(mod-R+L);
				}
			}
		}
		if(!rv)return;reverse(F+1,F+n);int I=power(n,mod-2);
		for(int i=0;i<n;++i)F[i]=1ll*F[i]*I%mod;
	}
	int Inv[maxn];
	void inv(int*F,int*G,int n){
		//G(x)=inv(F(x)) mod x^n;
		if(n==1)return G[0]=power(F[0],mod-2),void();
		inv(F,G,(n+1)>>1);for(int i=(n+1)>>1;i<n;++i)G[i]=0;
		int cp=n;initNTT((n+1)*2,n);
		for(int i=0;i<cp;++i)Inv[i]=F[i];for(int i=cp;i<n;++i)Inv[i]=G[i]=0;
		NTT(Inv,n,0);NTT(G,n,0);for(int i=0;i<n;++i)
			G[i]=1ll*G[i]*mo(mod-1ll*G[i]*Inv[i]%mod+2)%mod;
		NTT(G,n,1);for(int i=cp;i<n;++i)G[i]=0;
	}
	int Ln[maxn];
	void ln(int*F,int*G,int n){
		//G(x)=ln(F(x)) mod x^n;
		for(int i=0;i<n;++i)Ln[i]=0;
		inv(F,Ln,n);int cp=n;
		initNTT((n+1)*2,n);
		for(int i=0;i<cp;++i)G[i]=1ll*F[i+1]*(i+1)%mod;
		for(int i=cp;i<n;++i)G[i]=Ln[i]=0;NTT(G,n,0);NTT(Ln,n,0);
		for(int i=0;i<n;++i)G[i]=1ll*G[i]*Ln[i]%mod;NTT(G,n,1);
		for(int i=cp-1;i>=1;--i)G[i]=1ll*G[i-1]*power(i,mod-2)%mod;
		G[0]=0;for(int i=cp;i<n;++i)G[i]=0;
	}
	int Exp[maxn];
	void exp(int*F,int*G,int n){
		//G(x)=exp(F(x)) mod x^n;
		if(n==1)return G[0]=1,void();exp(F,G,(n+1)>>1);
		for(int i=(n+1)>>1;i<n;++i)G[i]=0;
		for(int i=0;i<n;++i)Exp[i]=0;ln(G,Exp,n);
		for(int i=0;i<n;++i)Exp[i]=mo(mod-Exp[i]+F[i]+(i==0));
		int cp=n;initNTT((n+1)*2,n);
		for(int i=cp;i<n;++i)Exp[i]=G[i]=0;NTT(G,n,0);NTT(Exp,n,0);
		for(int i=0;i<n;++i)G[i]=1ll*G[i]*Exp[i]%mod;
		NTT(G,n,1);for(int i=cp;i<n;++i)G[i]=0;
	}
	int Power[maxn];
	void power(int*F,int*G,int n,int m0,int m1,int m2){
		//There is something wrong with the code.However, I haven't find out where is the problem.
		//G(x)=power(F(x),m) mod x^n;
		//m0=m%mod m1=m%(mod-1) m2=stand for m
		if(m0==0){for(int i=0;i<n;++i)G[i]=(i==0);return;}
		int no=0;while(no<n&&F[no]==0)++no;
		if(1ll*no*m2>=n){for(int i=0;i<n;++i)G[i]=0;return;}
		int V=F[no],I=power(V,mod-2);
		for(int i=0;i+no<n;++i)G[i]=1ll*F[i+no]*I%mod,Power[i]=0;
		for(int i=n-no;i<n;++i)G[i]=Power[i]=0;ln(G,Power,n);
		for(int i=0;i<n;++i)Power[i]=1ll*Power[i]*m0%mod;
		exp(Power,G,n);V=power(V,m1);no*=m2;
		for(int i=n-1;i>=no;--i)G[i]=1ll*G[i-no]*V%mod;
		for(int i=no-1;i>=0;--i)G[i]=0;
	}
	int Divide0[maxn],Divide1[maxn];
	void divide(int*F,int*G,int*Q,int*R,int n,int m){
		//F(x)=Q(x)G(x)+R(x) Q(x)? R(x)? deg(F)=n-1 deg(G)=m-1
		int tn=n-m+1;
		for(int i=0;i<tn;++i)Divide1[i]=(m>=i+1?G[m-i-1]:0);
		inv(Divide1,Divide0,tn);
		for(int i=0;i<tn;++i)Divide1[i]=(n>=i+1?F[n-i-1]:0);
		int cp=tn;initNTT((n+1)*2,tn);
		NTT(Divide0,tn,0);NTT(Divide1,tn,0);
		for(int i=0;i<tn;++i)Q[i]=1ll*Divide0[i]*Divide1[i]%mod;
		NTT(Q,tn,1);for(int i=cp;i<tn;++i)Q[i]=0;reverse(Q,Q+cp);
		for(int i=0;i<tn;++i)Divide0[i]=Q[i],Divide1[i]=G[i];
		NTT(Divide0,tn,0);NTT(Divide1,tn,0);
		for(int i=0;i<tn;++i)R[i]=1ll*Divide0[i]*Divide1[i]%mod;
		NTT(R,tn,1);for(int i=0;i<tn;++i)R[i]=mo(mod-R[i]+F[i]);
	}
}
int F[maxn],sum[maxn],G[maxn],inv[maxn];
int main(){
	int n,cnt1=0,cnt2=0;read(n);
	for(int i=1;i<=n;++i){
		int v;read(v);
		if(v==1){
			++cnt1;
			++sum[1];
		}
		else if(v==2){
			++cnt2;
		}
		else{
			++sum[v-2];
		}
	}
	if(cnt1<2)puts("0");
	else{
		cnt1-=2;
		inv[1]=1;
		for(int i=2;i<=cnt1;++i)
			inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
		for(int i=1;i<=cnt1;++i)
			for(int j=1;i*j<=cnt1;++j)
				if((j-1)&1)F[i*j]=mo(mod-1ll*sum[i]*inv[j]%mod+F[i*j]);
				else F[i*j]=mo(1ll*sum[i]*inv[j]%mod+F[i*j]);
		polynomial::exp(F,G,cnt1+1);
		write(1ll*G[cnt1]*power(2,cnt2)%mod);pc('\n');
	}
	return 0;
}
/*
所以,永远不要问丧钟为谁而鸣,它为你而鸣。
*/

CF438E The Child and Binary Tree

题意简述

正整数集 \(S\) 里面的元素分别为 \(c_1,c_2,\dots,c_n\) ,对于每个 \(1\le i\le m\) ,询问有多少二叉树满足每个点的点权的值属于 \(S\) ,并且点权和为 \(i\) ,两棵二叉树不同当且仅当存在一个点点权不同或者存在一个点的左子树或右子树不同。

\(1\le n,m,c_i\le 10^5\) 。

题目分析

设 \(f_x\) 表示点权和为 \(x\) 的二叉树个数,默认 \(f_0=1\) ,那么有:

\[f_x=\sum_{i=1}^n\sum_{c_i+j+k=x}f_jf_k \]

设 \(F(x)=\sum_{i=0}^{\infty}f_ix^i\) ,那么有:

\[F(x)\equiv 1+\sum_{i=1}^nx^{c_i}F^2(x) \pmod {x^{m+1}} \]

设 \(H(x)=\sum_{i=1}^nx^{c_i}\) ,那么:

\[F(x)\equiv 1+F^2(x)H(x) \pmod {x^{m+1}} \]

\[F^2(x)H(x)-F(x)+1\equiv 0 \pmod {x^{m+1}} \]

套牛顿迭代,可以得到:

\[F_{2n}(x)\equiv F_n(x)-\frac{F_n^2(x)H(x)-F_n(x)+1}{2F_n(x)H(x)-1}\equiv \frac{1}{2}(F_n(x)+\frac{F_n(x)-2}{2F_n(x)H(x)-1}) \pmod {x^{2n}} \]

参考代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ch() getchar()
#define pc(x) putchar(x)
using namespace std;
template<typename T>void read(T&x){
	static char c;static int f;
	for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
	for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
}
template<typename T>void write(T x){
	static char q[65];int cnt=0;
	if(x<0)pc('-'),x=-x;
	q[++cnt]=x%10,x/=10;
	while(x)
		q[++cnt]=x%10,x/=10;
	while(cnt)pc(q[cnt--]+'0');
}
const int maxn=800005,mod=998244353,g_=3;
int mo(const int x){
	return x>=mod?x-mod:x;
}
int power(int a,int x){
	int re=1;
	while(x){
		if(x&1)re=1ll*re*a%mod;
		a=1ll*a*a%mod,x>>=1;
	}
	return re;
}
int rev[maxn];
void initNTT(int m,int&n){
	n=1;int cn=-1;
	while(n<=m)n<<=1,++cn;
	for(int i=0;i<n;++i)
		rev[i]=(rev[i>>1]>>1)|((i&1)<<cn);
}
void NTT(int*F,int n,int rv){
	for(int i=0;i<n;++i)if(rev[i]<i)
		F[rev[i]]^=F[i]^=F[rev[i]]^=F[i];
	for(int mid=1;mid<n;mid<<=1){
		const int len=mid<<1,gn=power(g_,(mod-1)/len);
		for(int i=0;i<n;i+=len){
			for(int j=0,g=1;j<mid;++j,g=1ll*g*gn%mod){
				int l=i+j,r=l+mid;
				int L=F[l],R=1ll*F[r]*g%mod;
				F[l]=mo(L+R),F[r]=mo(mod-R+L);
			}
		}
	}
	if(!rv)return;reverse(F+1,F+n);int I=power(n,mod-2);
	for(int i=0;i<n;++i)F[i]=1ll*F[i]*I%mod;
}
int Inv[maxn];
void inv(const int*F,int*G,int n){
	if(n==1)return G[0]=power(F[0],mod-2),void();
	int on=(n+1)>>1;inv(F,G,on);for(int i=on;i<n;++i)G[i]=0;
	int cp=n;initNTT((n+1)*2,n);for(int i=0;i<cp;++i)Inv[i]=F[i];
	for(int i=cp;i<n;++i)Inv[i]=G[i]=0;NTT(Inv,n,0);NTT(G,n,0);
	for(int i=0;i<n;++i)G[i]=1ll*G[i]*mo(mod-1ll*G[i]*Inv[i]%mod+2)%mod;
	NTT(G,n,1);for(int i=cp;i<n;++i)G[i]=0;
}
int S0[maxn],S1[maxn];
void solve(const int*F,int*G,int n){
	if(n==1)return G[0]=1,void();
	int on=(n+1)>>1;solve(F,G,on);for(int i=on;i<n;++i)G[i]=0;
	int cp=n;initNTT((n+1)*4,n);for(int i=0;i<cp;++i)S0[i]=F[i];
	for(int i=cp;i<n;++i)S0[i]=G[i]=0;NTT(G,n,0);NTT(S0,n,0);
	for(int i=0;i<n;++i)S0[i]=mo(mod-1+2ll*S0[i]*G[i]%mod);
	NTT(S0,n,1);inv(S0,S1,n=cp);initNTT((n+1)*4,n);for(int i=cp;i<n;++i)S1[i]=0;NTT(S1,n,0);
	for(int i=0;i<n;++i)G[i]=1ll*(mod+1)/2*mo(G[i]+1ll*mo(mod-2+G[i])*S1[i]%mod)%mod;
	NTT(G,n,1);for(int i=cp;i<n;++i)G[i]=0;
}
int F[maxn],G[maxn];
int main(){
	int n,m;read(n),read(m);
	while(n--){int c;read(c);F[c]=mo(F[c]+1);}
	solve(F,G,m+1);for(int i=1;i<=m;++i)write(G[i]),pc('\n');
	return 0;
}

小结

事实上,自己的多项式和生成函数还是搞得太浅了,没有深入,不过就先入个门吧,以后有时间了再继续搞一下。

标签:frac,函数,ln,int,多项式,笔记,pmod,2n,equiv
来源: https://www.cnblogs.com/lsq147/p/13798943.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有