首页 > 其他分享 >多项式1/10家桶

多项式1/10家桶

时间:2022-10-09 07:22:05浏览次数:55  
标签:10 lceil frac pmod 多项式 int 家桶 rceil equiv

多项式求逆

\[\begin{aligned} &F(x) * G(x) \equiv 1 \pmod{x^n} \\ &F(x) * G(x) \equiv 1 \pmod{x^{\lceil \frac{n}{2}\rceil}} \\ &我们设F(x)*H(x)\equiv 1 \pmod{x^{\lceil \frac{n}{2}\rceil}}\\ &F(x)*(G(x)-H(x)) \equiv 0 \pmod{x^{\lceil \frac{n}{2}\rceil}}\\ &(G(x)-H(x))\equiv 0 \pmod{x^{\lceil \frac{n}{2}\rceil}}\\ &(G(x)-H(x))^2\equiv 0 \pmod{x^n}\\ &G^2(x)+H^2(x)-2G(x)H(x)\equiv 0 \pmod{x^n}\\ &F(x)G^2(x)+F(x)H^2(x)-2F(x)G(x)H(x)\equiv 0 \pmod{x^n}\\ &G(x)+F(x)H^2(x)-2H(x)\equiv 0 \pmod{x^n}\\ & G(x)\equiv 2H(x)-F(x)H^2(x)\pmod{x^n}\\ &当n=1时,F(x)=[x^0]F(x)x,G(x)=([x^0]F(x)x)^{-1} \end{aligned} \]

很多题解都采用了上面的证法,然而我初次看时有很多不理解的地方。其中最令我感到迷惑的是为什么用向上取整而不能用向下取整。现在给出解释:

\[\begin{aligned} 1. &a \equiv 1 \pmod {x^n} \Rightarrow a\equiv 1 \pmod {x^{\lceil \frac{n}{2}\rceil}}\\ 证明: &a \equiv 1 \pmod {x^n}\\ &x^n \mid a-1\\ &{x^{\lceil \frac{n}{2}\rceil}}{x^{\lfloor \frac{n}{2} \rfloor}} \mid a-1\\ &{x^{\lceil \frac{n}{2}\rceil}}\mid a-1\\ &a \equiv 1 \pmod {x^{\lceil \frac{n}{2}\rceil}}\\ &注意到,向下取整同样满足这个性质,然而这并不重要(主不在乎\\ 2.&a\equiv 0 \pmod {x^{\lceil \frac{n}{2}\rceil}} \rightarrow a^2\equiv 0 \pmod{x^n}\\ 证明: &a^2 \equiv 0 \pmod {x^{2 {\lceil \frac{n}{2}\rceil}}}\\ & x^{{\lceil \frac{n}{2}\rceil}} \mid a^2\\ & x^n\mid x^{2 {\lceil \frac{n}{2}\rceil}} \\ &a^2 \equiv 0 \pmod {x^n}\\ &注意到,向下取整并不满足这个性质,因此只能采取向上取整的方式\\ \end{aligned} \]

有了这样的性质,最上面的证明自然就具有了正确性。

然而似乎并没有什么卵用,因为求逆是自底而上倍增实现的,根本用不着什么向下取整。

代码实现

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5+5e4;
const int P=998244353,g=3,gi=332748118;
int lim=1,r[maxn],c[maxn],w[maxn];
void joke()
{
    //joke说加个空函数跑的能快点
}


int fsp(int a,int b=P-2)
{
    int s=1;
    while(b)
    {
        if(b&1)s=1ll*s*a%P;
        b>>=1;
        a=1ll*a*a%P;
    }
    return s;
}
void init(int len)
{
    int l=0;
    lim=1;
    while(lim<=len)lim<<=1,l++;
    int wn=fsp(g,(P-1)/lim),cw=fsp(gi,(P-1)/lim);
    w[0]=c[0]=1;
    for(int i=1;i<lim;i++)
    {
        r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
        w[i]=1ll*w[i-1]*wn%P;
        c[i]=1ll*c[i-1]*cw%P;
    }
}
void NTT(int num[],int typ)
{
    for(int i=0;i<lim;i++)if(i<r[i])swap(num[i],num[r[i]]);
    if(typ==1)
    {
        for(int m=1,t=(lim>>1);m<lim;m<<=1,t>>=1)
        {
            for(int i=0;i<lim;i+=(m<<1))
            {
                for(int j=0;j<m;j++)
                {
                    int x=num[i+j],y=1ll*num[i+j+m]*w[t*j]%P;
                    num[i+j]=(x+y)%P;
                    num[i+j+m]=(x-y+P)%P;
                }
            }
        }
    }else{
        for(int m=1,t=(lim>>1);m<lim;m<<=1,t>>=1)
        {
            for(int i=0;i<lim;i+=(m<<1))
            {
                for(int j=0;j<m;j++)
                {
                    int x=num[i+j],y=1ll*num[i+j+m]*c[t*j]%P;
                    num[i+j]=(x+y)%P;
                    num[i+j+m]=(x-y+P)%P;
                }
            }
        }
        int invlen=fsp(lim);
        for(int i=0;i<lim;i++)
        {
            num[i]=1ll*num[i]*invlen%P;
        }
    }
}
void poly_mul(int a[],int b[],int len)
{
    init(len);
    NTT(a,1),NTT(b,1);
    for(int i=0;i<lim;i++)a[i]=1ll*a[i]*b[i]%P;
    NTT(a,-1);
}
void poly_inv(int a[],int b[],int len)
{
    int tmp[maxn];
    b[0]=fsp(a[0]);
    int op=1,ln=1;
    while(ln<=(len<<1))
    {
        init(ln);
        for(int i=0;i<ln;i++)tmp[i]=a[i];
        NTT(tmp,1),NTT(b,1);
        for(int i=0;i<lim;i++)b[i]=1ll*(1ll*2*b[i]-1ll*b[i]*b[i]%P*tmp[i]%P+P)%P;
        NTT(b,-1);
        for(int i=ln;i<lim;i++)b[i]=0;
        ln<<=1;
    }
}
int a[maxn],b[maxn];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    poly_inv(a,b,n);
    for(int i=0;i<n;i++)
    {
        cout<<b[i]<<" ";
    }
    return 0;
}

标签:10,lceil,frac,pmod,多项式,int,家桶,rceil,equiv
From: https://www.cnblogs.com/artalter/p/16770861.html

相关文章

  • 2022-10-08 本周纳斯达克三买三卖总结
    这一周总体就是个震荡趋势。做了周三和周五的空单。是按照,只要是中枢突破,出现三买三卖就开始做。日线来看,还在2个下降趋势线下面。 周三走势30分钟   5分钟图......
  • win10加入域后登录不显示本地帐户
    win10加入域后登录不显示本地帐户前言加入域后登录其他账户不显示原来的本地账户,需要输入本地账户的账户名等繁琐操作;通过改设置来简化操作,直接输入密码来登录本地账户。......
  • 10.8
    今日内容1.文件操作2.文件读写模式3.文件操作模式4.文件诸多方法5.文件内光标的移动1.文件操作1.文件的概念就是操作系统暴露给用户操作硬盘的快捷方式 eg:......
  • 10月8日内容总结——文件操作之文本模式和二进制模式、文件内光标的移动
    目录一、文件操作1、概念讲解2、通过代码打开文件的两种方式方式一:方法二:一些小知识点总结:二、文件的读写模式1、只读模式(r)2、只写模式(w)3、只追加模式(a)三、文件的操作模式......
  • 贤鱼的刷题日常--P1023 [NOIP2000 普及组] 税收与补贴问题--题目详解
    >......
  • 10.6题目大赏
    2022-10-6T1炼心题目背景\(Cafeiin\)神情认真,专心的听着老师讲话。“既然你已拜入算法门下,我便为你讲讲这算法的修炼之道,算法之道,分几重境界,初入编程,便是普及,普及之上......
  • ubuntu win10链接增加命令
    转载来源:使用Windows远程桌面工具来远程连接控制Ubuntu系统:http://www.safebase.cn/article-258275-1.html介绍有时需要在实际的电脑上安装Ubuntu的操作系统来搭建免费......
  • RE : 从零开始学习多项式(重制版)
    原版在这感觉原版讲得太仓促了,很多技巧性的东西但是没有什么根本性的解释,所以有了重置版。重制版预估还会加入很多新的东西,希望我能在一周内完工[双手合十]。目录多项......
  • 【10月】C语言学习第1天
    指针符号&和*&用于指向变量数据位置,用十六进制表示*用于指向变量内存储的值-----------------------------------------函数对变量进行操控:由于函数返回只有一个值,固......
  • 做题记录整理图论2 P1600 [NOIP2016 提高组] 天天爱跑步(2022/10/4)
    P1600[NOIP2016提高组]天天爱跑步题解由于这位大佬似乎afo(?)了,所以我没搞懂那个桶怎么处理,到时候要回来再看一遍#include<bits/stdc++.h>#definefor1(i,a,b)for(in......