$\newcommand{align}[1]{\begin{align*}#1\end{align*}}$题意:给出$f(x)=\prod\limits_{i=1}^n(a_ix+1)$和$g(x)=\prod\limits_{j=1}^m(b_jx+1)$的各项系数,求$h(x)=\prod\limits_{i=1}^n\prod\limits_{j=1}^m(a_ib_jx+1)$的前$k$项系数

乘积的形式不好处理,取个$\ln$就可以化为和的形式

$\align{\ln(a_ix+1)=\int\frac{a_i}{a_ix+1}\mathrm dx=\sum\limits_{k\geq1}\dfrac{(-1)^{k+1}}ka_i^kx^k}$

$\align{\ln(b_jx+1)=\sum\limits_{k\geq1}\dfrac{(-1)^{k+1}}kb_j^kx^k}$

$\align{\ln(a_ib_jx+1)=\sum\limits_{k\geq1}\dfrac{(-1)^{k+1}}ka_i^kb_j^kx^k}$

容易发现我们把前两个式子的系数做点积,再对$\forall k\geq1$把第$k$位乘上$(-1)^{-k+1}k$就得到了第三个式子的系数

所以我们把$\ln f(x)$和$\ln g(x)$的系数如此处理后就得到了$\ln h(x)$的系数,$\exp$回去即可

#include<stdio.h>
#include<string.h>
typedef long long ll;
const int mod=998244353,maxn=262144;
void swap(int&a,int&b){a^=b^=a^=b;}
int mul(int a,int b){return a*(ll)b%mod;}
int ad(int a,int b){return(a+b)%mod;}
int de(int a,int b){return(a-b)%mod;}
int pow(int a,int b){
	int s=1;
	while(b){
		if(b&1)s=mul(s,a);
		a=mul(a,a);
		b>>=1;
	}
	return s;
}
int rev[maxn],N,iN;
void pre(int n){
	int i,k;
	for(N=1,k=0;N<n;N<<=1)k++;
	for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
	iN=pow(N,mod-2);
}
void ntt(int*a,int on){
	int i,j,k,t,w,wn;
	for(i=0;i<N;i++){
		if(i<rev[i])swap(a[i],a[rev[i]]);
	}
	for(i=2;i<=N;i<<=1){
		wn=pow(3,on==1?(mod-1)/i:(mod-1-(mod-1)/i));
		for(j=0;j<N;j+=i){
			w=1;
			for(k=0;k<i>>1;k++){
				t=mul(w,a[i/2+j+k]);
				a[i/2+j+k]=de(a[j+k],t);
				a[j+k]=ad(a[j+k],t);
				w=mul(w,wn);
			}
		}
	}
	if(on==-1){
		for(i=0;i<N;i++)a[i]=mul(a[i],iN);
	}
}
int t0[maxn];
void getinv(int*a,int*b,int n){
	if(n==1){
		b[0]=pow(a[0],mod-2);
		return;
	}
	int i;
	getinv(a,b,n>>1);
	pre(n<<1);
	memset(t0,0,N<<2);
	memcpy(t0,a,n<<2);
	ntt(t0,1);
	ntt(b,1);
	for(i=0;i<N;i++)b[i]=mul(b[i],2-mul(b[i],t0[i]));
	ntt(b,-1);
	for(i=n;i<N;i++)b[i]=0;
}
int t1[maxn],inv[maxn];
void getln(int*a,int*b,int n){
	int i;
	memset(t1,0,n<<3);
	getinv(a,t1,n);
	for(i=1;i<n;i++)b[i-1]=mul(i,a[i]);
	ntt(b,1);
	ntt(t1,1);
	for(i=0;i<N;i++)b[i]=mul(b[i],t1[i]);
	ntt(b,-1);
	for(i=n-1;i>0;i--)b[i]=mul(b[i-1],inv[i]);
	b[0]=0;
	for(i=n;i<N;i++)b[i]=0;
}
int t2[maxn];
void exp(int*a,int*b,int n){
	if(n==1){
		b[0]=1;
		return;
	}
	int i;
	exp(a,b,n>>1);
	memset(t2,0,n<<3);
	getln(b,t2,n);
	for(i=0;i<n;i++)t2[i]=de(a[i],t2[i]);
	t2[0]++;
	ntt(b,1);
	ntt(t2,1);
	for(i=0;i<N;i++)b[i]=mul(b[i],t2[i]);
	ntt(b,-1);
	for(i=n;i<N;i++)b[i]=0;
}
int f[maxn],g[maxn],lf[maxn],lg[maxn],lh[maxn],h[maxn];
int main(){
	int N,n,m,k,i;
	scanf("%d%d%d",&n,&m,&k);
	for(i=0;i<=n;i++)scanf("%d",f+i);
	for(i=0;i<=m;i++)scanf("%d",g+i);
	for(N=1;N<n+1||N<m+1||N<k+1;N<<=1);
	inv[1]=1;
	for(i=2;i<N;i++)inv[i]=-mul(mod/i,inv[mod%i]);
	getln(f,lf,N);
	getln(g,lg,N);
	for(i=0;i<N;i++)lh[i]=mul(mul(lf[i],lg[i]),i&1?i:-i);
	exp(lh,h,N);
	for(i=0;i<k;i++)printf("%d ",ad(h[i],mod));
}

[xsy2978]Product of Roots的更多相关文章

  1. 【xsy2978】Product of Roots 生成函数+多项式ln+多项式exp

    题目大意:给你两个多项式$f(x)$和$g(x)$,满足$f(x)=\prod\limits_{i=1}^{n}(a_i+1)$,$g(x)=\prod\limits_{i=1}^{m}(b_i+1) ...

  2. XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof

    A. City Wall 找规律. #include<stdio.h> #include<iostream> #include<string.h> #include ...

  3. gc roots 垃圾回收

    gc roots包括以下几个: 虚拟机栈(栈桢中的本地变量表)中的引用对象 方法区中的类静态属性引用的对象 方法区中的常量引用的对象 本地方法栈中JNI(即native方法)的引用的对象 java,c ...

  4. uva 11059 maximum product(水题)——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAB1QAAAMcCAIAAABo0QCJAAAgAElEQVR4nOydW7msuhKF2wIasIAHJK

  5. [LeetCode] Product of Array Except Self 除本身之外的数组之积

    Given an array of n integers where n > 1, nums, return an array output such that output[i] is equ ...

  6. [LeetCode] Maximum Product Subarray 求最大子数组乘积

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. vector - vector product

    the inner product Givens two vectors \(x,y\in \mathbb{R}^n\), the quantity \(x^\top y\), sometimes c ...

  8. 1 Maximum Product Subarray_Leetcode

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  9. Leetcode Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

随机推荐

  1. 如何在Javascript中利用封装这个特性

    对于熟悉C#和Java的兄弟们,面向对象的三大思想(封装,继承,多态)肯定是了解的,那么如何在Javascript中利用封装这个特性呢? 我们会把现实中的一些事物抽象成一个Class并且把事物的属性( ...

  2. bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二类斯特林数 等比数列求和优化

    [Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 679  Solved: 534[Submit][S ...

  3. <video>标签的特性

    以前的网页视频 过去还没有HTML5的时候,我们处理网页视频的时候,都是通过Flash插件来实现的,然而,并非所有浏览器都有同样的插件. 现在有了HTML5带来的video元素,开发者能够很方便地将视 ...

  4. SpringMVC学习 -- @RequestParam , @RequestHeader , @CookieValue 的使用

    使用 @RequestParam 绑定请求参数值: value:参数名 , 仅有一个 value 属性时 , value 可以省略不写. required:是否必须.默认为 true , 表示请求参数 ...

  5. express添加拦截器

    var express = require('express')   , routes = require('./routes')   , http = require('http')   , pat ...

  6. mybatis的一些特殊符号标识(大于,小于,等于,不等于)

    特殊字符   替代符号(红色基本为常用的)    &            &      <            <      >            > ...

  7. USACO_1.1_Your_Ride_Is_Here_(字符串+水题)

    描述 http://train.usaco.org/usacoprob2?a=y0SKxY0Kc2q&S=ride 给出两个由大写字母组成,长度不大于$6$的字符串. 将字符串中的各字母的字典 ...

  8. 【STSRM12】夏令营(分治决策单调+主席树)

    [题意]n个数字分成k段,每一段的价值是段内不同数字的个数,求最大价值.n<=35000,k<=50. [算法]分治决策单调+主席树(可持久化线段树) [题解] f[i][j]表示前i天分 ...

  9. 【洛谷 P3846】 [TJOI2007]可爱的质数 (BSGS)

    题目链接 \(BSGS\)模板题..不会点这里 #include <cstdio> #include <cmath> #include <map> using na ...

  10. springboot 全局异常处理

    springboot 全局异常处理 研究了半天springboot的全局异常处理,虽然还是需要再多整理一下,但是对于常见的404和500足以可以区分开,能够根据这两个异常分别处理 首先配置视图解析路径 ...