zoukankan      html  css  js  c++  java
  • 洛谷 P4238 [模板] 多项式求逆

    题目:https://www.luogu.org/problemnew/show/P4238

    看博客:https://www.cnblogs.com/xiefengze1/p/9107752.html

    https://www.cnblogs.com/Mychael/p/9045143.html

    注意那个 ( leftlceil n/2 ight ceil ),因为如果 n = 6,那么 6 = 0+6 = 1+5 = 2+4 = 3+3,对 0,1,2,3 都有要求,所以下一层传 3;

    而如果 n = 7,那么 7 = 0+7 = 1+6 = 2+5 = 3+4,对 0,1,2,3,4 都有要求,所以下一层传 4;

    然后要注意每次要重新算 rev[i],因为长度变了!

    别忘了实际的取模,就是把 n 及以上的系数都变成0。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int const xn=(1<<18),mod=998244353,g=3;
    int n,a[xn],b[xn],c[xn],rev[xn];
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    ll pw(ll a,int b)
    {
      ll ret=1;
      for(;b;b>>=1,a=(a*a)%mod)if(b&1)ret=(ret*a)%mod;
      return ret;
    }
    int upt(int x){while(x>=mod)x-=mod; while(x<0)x+=mod; return x;}
    
    void ntt(int *a,int tp,int lim)
    {
      for(int i=0;i<lim;i++)
        if(i<rev[i])swap(a[i],a[rev[i]]);
      for(int mid=1;mid<lim;mid<<=1)
        {
          int wn=pw(g,(mod-1)/(mid<<1));
          if(tp==-1)wn=pw(wn,mod-2);//!!!
          for(int j=0,len=(mid<<1);j<lim;j+=len)
        {
          int w=1;
          for(int k=0;k<mid;k++,w=(ll)w*wn%mod)
            {
              int x=a[j+k],y=(ll)w*a[j+mid+k]%mod;
              a[j+k]=upt(x+y); a[j+mid+k]=upt(x-y);
            }
        }
        }
      if(tp==1)return; int inv=pw(lim,mod-2);
      for(int i=0;i<lim;i++)a[i]=(ll)a[i]*inv%mod;
    }
    void inv(int n,int *a,int *b)
    {
      if(n==1){b[0]=pw(a[0],mod-2); return;}
      inv((n+1)>>1,a,b);
      int lim=1,l=0;
      while(lim<=n+n)lim<<=1,l++;
      for(int i=0;i<lim;i++)
        rev[i]=((rev[i>>1]>>1)|((i&1)<<(l-1)));//!!!
      for(int i=0;i<n;i++)c[i]=a[i];
      for(int i=n;i<lim;i++)c[i]=0;
      ntt(b,1,lim); ntt(c,1,lim);
      for(int i=0;i<lim;i++)b[i]=upt((((ll)2-(ll)c[i]*b[i])%mod*b[i])%mod);
      ntt(b,-1,lim);
      for(int i=n;i<lim;i++)b[i]=0;//!
    }
    int main()
    {
      n=rd();
      for(int i=0;i<n;i++)a[i]=rd();
      inv(n,a,b);
      for(int i=0;i<n;i++)printf("%d ",b[i]); puts("");
      return 0;
    }
  • 相关阅读:
    jquery animate()方法 语法
    jquery unload方法 语法
    jquery undelegate()方法 语法
    jquery unbind()方法 语法
    jquery trigger() 方法 语法
    jquery toggle()方法 语法
    jquery change() 函数 语法
    jquery blur()函数 语法
    jquery bind()方法 语法
    jquery checked选择器 语法
  • 原文地址:https://www.cnblogs.com/Zinn/p/10040800.html
Copyright © 2011-2022 走看看