多项式求逆

介绍

准确来说,是求多项式的逆元。

对于多项式 A ( x ) A(x) A(x),如果存在 A ( x ) B ( x ) ≡ 1 ( m o d x n ) A(x)B(x)\equiv 1 \pmod {x^n} A(x)B(x)1(modxn),那么称 B ( x ) B(x) B(x) A ( x ) A(x) A(x) 在模 x n x^n xn 意义下的逆元。

注意,这里的模 x n x^n xn,是指舍弃含有 x n x^n xn 及更高次的项。

比如说有一个多项式: 5 + x + 6 x 2 + 3 x 3 + 2 x 4 5+x+6x^2+3x^3+2x^4 5+x+6x2+3x3+2x4,这个多项式对 x 3 x^3 x3 取模后,就是 5 + x + 6 x 2 5+x+6x^2 5+x+6x2

正题

假如 A ( x ) B ( x ) ≡ 1 ( m o d x n ) A(x)B(x)\equiv 1 \pmod {x^n} A(x)B(x)1(modxn),那么也就是说, A ( x ) A(x) A(x) B ( x ) B(x) B(x) 在模 x n x^n xn 意义下相乘得到的多项式,只有常数项为 1 1 1,其他项的系数都为 0 0 0

引理   如果满足 A ( x ) B ( x ) ≡ 1 ( m o d x n ) A(x)B(x)\equiv 1 \pmod {x^n} A(x)B(x)1(modxn),那么肯定也满足 A ( x ) B ( x ) ≡ 1 ( m o d x m )    ( 1 ≤ m ≤ n ) A(x)B(x)\equiv 1 \pmod {x^m}~~(1\leq m \leq n) A(x)B(x)1(modxm)  (1mn),这是下面扯淡的一个大前提,所以稍稍证明一下还是有必要的。

我们设 C ( x ) = A ( x ) B ( x ) ( m o d x n ) C(x)=A(x)B(x) \pmod{x^n} C(x)=A(x)B(x)(modxn),那么有: C i = ∑ j = 0 i A j B i − j ( m o d x n ) C_i=\sum_{j=0}^i A_jB_{i-j} \pmod {x^n} Ci=j=0iAjBij(modxn),也就是说, C i C_i Ci 只跟 A ( x ) , B ( x ) A(x),B(x) A(x),B(x) 的第 j    ( j ≤ i ) j~~(j\leq i) j  (ji) 项有关,那么在舍弃掉第 i i i 项以上的项时,并不会对 C i C_i Ci 产生影响。

由此可知,当舍弃掉 x m x^m xm 及以上的项时,并不会影响 C m − 1 C_{m-1} Cm1 及以下的项。

于是 A ( x ) B ( x ) ≡ 1 ( m o d x m )    ( 1 ≤ m ≤ n ) A(x)B(x) \equiv 1 \pmod{x^m}~~(1\leq m \leq n) A(x)B(x)1(modxm)  (1mn) 成立。

于是我们就可以愉快地推柿子了:

B ( x ) B(x) B(x) A ( x ) A(x) A(x) 在模 x n x^n xn 意义下的逆元, G ( x ) G(x) G(x) A ( x ) A(x) A(x) 的在模 x ⌈ n 2 ⌉ x^{\lceil \frac n 2 \rceil} x2n 意义下的逆元(事实上由上面的引理可知, G G G 也就是 B B B x ⌈ n 2 ⌉ x^{\lceil \frac n 2 \rceil} x2n 后得到的多项式)。

那么有
G ( x ) ≡ B ( x ) ( m o d x ⌈ n 2 ⌉ ) B ( x ) − G ( x ) ≡ 0 ( m o d x ⌈ n 2 ⌉ ) ( B ( x ) − G ( x ) ) 2 ≡ 0 ( m o d x n ) B ( x ) 2 − 2 B ( x ) G ( x ) + G ( x ) 2 ≡ 0 ( m o d x n ) G(x)\equiv B(x) \pmod {x^{\lceil \frac n 2 \rceil}}\\ B(x)-G(x)\equiv 0 \pmod {x^{\lceil \frac n 2 \rceil}}\\ (B(x)-G(x))^2\equiv 0 \pmod {x^n}\\ B(x)^2-2B(x)G(x)+G(x)^2\equiv 0 \pmod {x^n}\\ G(x)B(x)(modx2n)B(x)G(x)0(modx2n)(B(x)G(x))20(modxn)B(x)22B(x)G(x)+G(x)20(modxn)

让整个柿子乘上 A ( x ) A(x) A(x),那么有:
A ( x ) B ( x ) B ( x ) − 2 A ( x ) B ( x ) G ( x ) + A ( x ) G ( x ) 2 ≡ 0 ( m o d x n ) A(x)B(x)B(x)-2A(x)B(x)G(x)+A(x)G(x)^2\equiv 0 \pmod {x^n}\\ A(x)B(x)B(x)2A(x)B(x)G(x)+A(x)G(x)20(modxn)

因为 A ( x ) B ( x ) ≡ 1 ( m o d x n ) A(x)B(x)\equiv 1 \pmod {x^n} A(x)B(x)1(modxn),所以有
B ( x ) − 2 G ( x ) + A ( x ) G ( x ) 2 ≡ 0 ( m o d x n ) B ( x ) ≡ 2 G ( x ) − A ( x ) G ( x ) 2 ( m o d x n ) B ( x ) ≡ G ( x ) ( 2 − A ( x ) G ( x ) ) ( m o d x n ) B(x)-2G(x)+A(x)G(x)^2\equiv 0 \pmod {x^n}\\ B(x)\equiv 2G(x)-A(x)G(x)^2 \pmod {x^n}\\ B(x)\equiv G(x)(2-A(x)G(x)) \pmod {x^n}\\ B(x)2G(x)+A(x)G(x)20(modxn)B(x)2G(x)A(x)G(x)2(modxn)B(x)G(x)(2A(x)G(x))(modxn)

这说明,我们可以通过 G ( x ) G(x) G(x) 求得 B ( x ) B(x) B(x)

然后像倍增一样搞,从小往大推即可。

对于里面 A ( x ) G ( x ) A(x)G(x) A(x)G(x) 这个部分,因为答案要求对 998244353 998244353 998244353 取模,所以用 N T T NTT NTT 搞一搞即可。

代码如下:

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 300010
#define ll long long
#define mod 998244353

int n;
ll ksm(ll x,ll y)
{
	ll re=1,tot=x;
	while(y)
	{
		if(y&1)re=re*tot%mod;
		tot=tot*tot%mod;
		y>>=1;
	}
	return re;
}
#define inv(x) ksm(x,mod-2)
int up,l,r[maxn];
void work(int len)
{
	for(l=0,up=1;up<=len;up<<=1,l++);
	for(int i=1;i<up;i++)
	r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
}
ll a[maxn],b[maxn];
const int G=3,invG=inv(G);
void ntt(ll *f,int len,int type)
{
	for(int i=1;i<len;i++)
	if(i<r[i])swap(f[i],f[r[i]]);
	for(int mid=1;mid<len;mid<<=1)
	{
		ll wn=ksm((type==1?G:invG),(mod-1)/mid>>1);
		for(int block=mid<<1,j=0;j<len;j+=block)
		{
			ll w=1;
			for(int i=j;i<j+mid;i++,w=w*wn%mod)
			{
				int x=f[i],y=f[i+mid]*w%mod;
				f[i]=(x+y)%mod;f[i+mid]=(x-y+mod)%mod;
			}
		}
	}
}
void solve(int len,ll *f,ll *g)
{
	if(len==1){g[0]=inv(f[0]);return;}
	solve((len+1)>>1,f,g);
	work(len+n);
	for(int i=0;i<up;i++)
	a[i]=f[i],b[i]=(i<(len+1)>>1?g[i]:0);
	ntt(a,up,1);ntt(b,up,1);
	for(int i=0;i<up;i++)
	a[i]=b[i]*((2-a[i]*b[i]%mod+mod)%mod)%mod;
	ntt(a,up,-1);
	int invup=inv(up);
	for(int i=0;i<len;i++)
	g[i]=a[i]*invup%mod;
}
ll f[maxn],g[maxn];

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	scanf("%lld",&f[i]);
	solve(n,f,g);
	for(int i=0;i<n;i++)
	printf("%lld ",g[i]);
}

可能还会更新的题表

【模板】分治 FFT   题解
射命丸文的笔记   题解
[国家集训队]整数的lqp拆分   题解

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要将多项式化成不定积分,可以使用多项式的基本积分公式。根据这个公式,对于任何一个多项式,它的不定积分都可以表示为其各项系数的积分。 例如,对于一个多项式 f(x) = 2x^3 + 3x^2 + 4x + 5,它的不定积分可以表示为: ∫(2x^3 + 3x^2 + 4x + 5)dx = (2/4)x^4 + (3/3)x^3 + (4/2)x^2 + 5x + C 其中,C 为任意常数项。 因此,多项式可以通过使用基本积分公式来化成不定积分。 ### 回答2: 要将多项式转化为不定积分,可以按照以下步骤进行操作: 1. 首先,将多项式按照降幂排列,即从高次到低次的顺序排列各项。 2. 对于每一项,根据幂的规则,可以将其转化为不定积分。具体而言,对于幂函数 $x^n$,其中 $n$ 是一个实数,不定积分为 $\frac{1}{n+1}x^{n+1}+C$,其中 $C$ 是一个常数。例如,$x^3$ 的不定积分为 $\frac{1}{4}x^4+C$。 3. 将每一项的不定积分相加,得到整个多项式的不定积分。注意,由于不定积分是线性的,可以分别对每一项进行不定积分,然后将结果相加。 4. 最后,记得在结果中添加常数项 $C$,表示原函数的不确定性。这是因为不定积分得到的是一个函数族,只有添加常数项才能表示出具体的函数。 总之,将多项式化为不定积分的具体步骤包括:按照降幂排列多项式各项,对每一项应用幂函数的不定积分规则,相加得到整个多项式的不定积分,并在结果中添加常数项。 ### 回答3: 多项式的不定积分是一个常见的求解方法,可以将一个多项式化成它的原函数。要将一个多项式进行不定积分,可以使用多项式的求导逆运算——积分来实现。 首先,将多项式的各项按照次数降序排列。然后,对于每一项,将其指数加1,并且将系数除以新的指数,得到新的项。这个过程相当于将每一项的幂函数求积分。 例如,对于一个多项式f(x) = 3x² + 2x + 1,可以按照次数降序排列为f(x) = 3x² + 2x + 1。对于每一项,将指数加1并且将系数除以新的指数,得到f(x) = x³ + x² + x。这样,多项式f(x)的不定积分就是F(x) = 1/4x⁴ + 1/3x³ + 1/2x² + C,其中C为常数。 总结起来,将每一项的指数加1,并将系数除以新的指数,就可以得到多项式的不定积分。当然,在计算过程中要注意处理常数项,保留常数项的不定积分时需要加上常数C。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值