当前位置: 首页 > article >正文

P4725 【模板】多项式对数函数(多项式 ln)

洛谷P4725 【模板】多项式对数函数(多项式 ln)

题目大意

给你一个 n − 1 n-1 n1次多项式 A ( x ) A(x) A(x),求一个   m o d   x n \bmod x^n modxn下的多项式 B ( x ) B(x) B(x),满足 B ( x ) ≡ ln ⁡ A ( x ) B(x)\equiv \ln A(x) B(x)lnA(x)

  m o d   998244353 \bmod 998244353 mod998244353下进行, a i ∈ [ 0 , 998244353 ) a_i\in[0,998244353) ai[0,998244353)且为整数。

保证 a 0 = 1 a_0=1 a0=1

n ≤ 1 0 5 n\leq 10^5 n105


题解

前置知识:多项式乘法逆

依题意, B ( x ) = ln ⁡ A ( x ) B(x)=\ln A(x) B(x)=lnA(x),两边同时求导得

B ′ ( x ) = A ′ ( x ) A ( x ) B'(x)=\dfrac{A'(x)}{A(x)} B(x)=A(x)A(x)

A ( x ) A(x) A(x)进行多项式乘法逆求出 1 A ( x ) \dfrac{1}{A(x)} A(x)1,然后根据求导法则求出 A ′ ( x ) A'(x) A(x)。然后 B ′ ( x ) = A ′ ( x ) ⋅ 1 A ( x ) B'(x)=A'(x)\cdot \dfrac{1}{A(x)} B(x)=A(x)A(x)1,再积分一下得到 B ( x ) B(x) B(x)

因为常数项 a 0 = 1 a_0=1 a0=1,所以 B ( x ) B(x) B(x)的常数项 b 0 = 0 b_0=0 b0=0

时间复杂度为 O ( n log ⁡ 2 n ) O(n\log^2 n) O(nlog2n)

求导和积分

( x n ) ′ = n x n − 1 (x^n)'=nx^{n-1} (xn)=nxn1

∫ x n d x = 1 n + 1 x n + 1 \int x^ndx=\dfrac{1}{n+1}x^{n+1} xndx=n+11xn+1

code

#include<bits/stdc++.h>
using namespace std;
long long w,wn,f[500005],g[500005],a1[500005];
const long long G=3,mod=998244353;
long long mi(long long t,long long v){
	if(!v) return 1;
	long long re=mi(t,v/2);
	re=re*re%mod;
	if(v&1) re=re*t%mod;
	return re;
}
void ch(long long *a,int l){
	for(int i=1,j=l/2;i<l-1;i++){
		if(i<j) swap(a[i],a[j]);
		int k=l/2;
		while(j>=k){
			j-=k;k>>=1;
		}
		j+=k;
	}
}
void ntt(long long *a,int l,int fl){
	for(int i=2;i<=l;i<<=1){
		if(fl==1) wn=mi(G,(mod-1)/i);
		else wn=mi(G,mod-1-(mod-1)/i);
		for(int j=0;j<l;j+=i){
			w=1;
			for(int k=j;k<j+i/2;k++,w=w*wn%mod){
				long long t=a[k],u=w*a[k+i/2]%mod;
				a[k]=(t+u)%mod;
				a[k+i/2]=(t-u+mod)%mod;
			}
		}
	}
	if(fl==-1){
		long long ny=mi(l,mod-2);
		for(int i=0;i<l;i++) a[i]=a[i]*ny%mod;
	}
}
void solve(int l){
	if(l==1){
		g[0]=mi(f[0],mod-2);
		return;
	}
	solve((l+1)/2);
	int len=1;
	while(len<2*l) len<<=1;
	for(int i=0;i<l;i++) a1[i]=f[i];
	for(int i=l;i<len;i++) a1[i]=0;
	ch(a1,len);ch(g,len);
	ntt(a1,len,1);
	ntt(g,len,1);
	for(int i=0;i<len;i++){
		g[i]=(2-a1[i]*g[i]%mod+mod)%mod*g[i]%mod;
	}
	ch(g,len);
	ntt(g,len,-1);
	for(int i=l;i<len;i++) g[i]=0;
}
void qiudao(long long *a,int l){
	for(int i=0;i<l;i++) a[i]=a[i+1]*(i+1)%mod;
	a[l-1]=0;
}
void jifen(long long *a,int l){
	for(int i=l;i>=1;i--) a[i]=a[i-1]*mi(i,mod-2)%mod;
	a[0]=0;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&f[i]);
	}
	solve(n);
	int len=1;
	while(len<n*2) len<<=1;
	qiudao(f,len);
	ch(f,len);ch(g,len);
	ntt(f,len,1);ntt(g,len,1);
	for(int i=0;i<len;i++) f[i]=f[i]*g[i]%mod;
	ch(f,len);
	ntt(f,len,-1);
	jifen(f,len);
	for(int i=0;i<n;i++){
		printf("%lld ",f[i]);
	}
	return 0;
}

http://www.kler.cn/a/17310.html

相关文章:

  • Java 多线程(三)—— 死锁
  • 信号-3-信号处理
  • 鸿蒙next版开发:相机开发-适配不同折叠状态的摄像头变更(ArkTS)
  • 阿里云通义大模型团队开源Qwen2.5-Coder:AI编程新纪元
  • ubuntu20.04 解决Pytorch默认安装CPU版本的问题
  • 【设计模式】行为型模式(二):策略模式、命令模式
  • MobileNet(V1、V2、V3)入门
  • 状态机模式
  • 男子订民宿被毁约5个家庭漂泊街头 房东:住满了,没办法
  • Maven 知识点总结
  • 日撸 Java 三百行day38
  • Springboot +Flowable,任务认领和回退(一)
  • 【JavaEE】应用层自定义协议及UDP协议
  • 【技术选型】Elasticsearch 和Solr那个香?
  • shell脚本 cut工具
  • 智能交通:从车牌识别到城市智能停车
  • Linux 中实现 ssh 免密登录
  • 联通云正式启动“同舟计划”,点燃数字引擎赋能产业未来
  • 100+Python挑战性编程练习系列 -- day 3
  • 2008-2019年主要城市PITI指数
  • 简单有趣的轻量级网络 Efficientnet(网络结构详解+详细注释代码+核心思想讲解)——pytorch实现
  • 华为OD机试 - 快递业务站(Python)
  • 三分钟教你看懂 spring 官方文档
  • 【ansys】project may be corrupted and recovery information is available
  • 达梦:dts工具迁移mysql decimal(65,30)的字段,报精度超出定义
  • 净利润下滑13%,帅丰电器已掉队?