Do a polynomial title notes

(Good morning, notes in a comment.)

 

Polynomial convolution template:

FFT:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int N=3e6+10;
double pi=acos(-1);
int n,m;
struct node{
    double x,y;
    node(double a=0,double b=0){
        x = a, y = b;
    }
    node operator + (node const &u) const{
        return node(x+u.x,y+u.y);
    }
    node operator - (node const &u) const{
        return node(x-u.x,y-u.y);
    }
    node operator * (node const &u) const{
        return node(x*u.x-y*u.y,y*u.x+x*u.y);
    }
}f[N];
int pos[N];
void fft(node *f,bool flag){
    for(int i=0;i<n;i++){
        if(i<pos[i])swap(f[i],f[pos[i]]);
    }
    for(int p=2;p<=n;p<<=1){
        int len=p>>1;
        node for (cos ( 2 * pi / p), I ( 2 * pi / p));
        if (! flag) fir.y * = - 1 ;
        for ( int k = 0 ; k <n; k + = p) {
            node buf(1,0);
            for(int l=k;l<k+len;l++){
                node tt = f * buf [len + l];
                f [len + l] = f [the] - tt;
                in [] = f [t] + tt;
                buf=buf*fir;
            }
        }
    }
}
int main ()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++)scanf("%lf",&f[i].x);
    for(int i=0;i<=m;i++)scanf("%lf",&f[i].y);
    for(m+=n,n=1;n<=m;n<<=1);
    for(int i=0;i<n;i++){
        pos[i]=(pos[i>>1]>>1)|((i&1)?n>>1:0);
    }
    fft(f,1);
    for(int i=0;i<n;i++)f[i]=f[i]*f[i];
    fft(f,0);
    for(int i=0;i<=m;i++)printf("%d ",(int)(f[i].y/n/2+0.5));
    return 0;
}
// the FFT compare throw accuracy, if need convolution polynomial coefficients range that much difference, the card will be precision
 // three times greater precision optimization becomes twice the upper limit of the span involved, serious off accuracy
[Template] polynomial multiplication (FFT)

NTT:

#include<iostream>
#include<cstdio>
using namespace std;
const int N=3e6+10,mod=998244353,G=3;
int n,m,pos[N];
long long f[N],g[N],invn,invG;
long long pw(long long x,long long k){
    long long num=1;
    while(k){
        if(k&1)num=num*x%mod;
        x=x*x%mod;
        k>>=1;
    }
    return num;
}
void ntt(long long *f,bool flag){
    for(int i=0;i<n;i++){
        if(i<pos[i])swap(f[i],f[pos[i]]);
    }
    for(int p=2;p<=n;p<<=1){
        int len=p>>1;
        long long fir=pw((flag?G:invG),(mod-1)/p);
        for(int i=0;i<n;i+=p){
            long long bur=1;
            for(int l=i;l<i+len;l++){
                long long tt=bur*f[l+len]%mod;
                f [l + len] = ((f [l] -tT)% v + v)% v;
                f[l]=(f[l]+tt)%mod;
                bur = bur *% for mod;
                
            }
        }
    }
}
int main ()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++)scanf("%lld",&f[i]);
    for(int i=0;i<=m;i++)scanf("%lld",&g[i]);
    for(m+=n,n=1;n<=m;n<<=1);
    for(int i=0;i<n;i++){
        pos[i]=(pos[i>>1]>>1)|((i&1)?(n>>1):0);
    }
    invn=pw(n,mod-2),invG=pw(G,mod-2);
    ntt(f,1),ntt(g,1);
    for(int i=0;i<n;i++){
        f[i]=f[i]*g[i]%mod;
    }
    ntt(f,0);
    for(int i=0;i<=m;i++){
        printf("%lld ",f[i]*invn%mod);
    }
    return 0;
} 
// array needs to open more than a power of 2, not twice
 // first unit 1 starts from the root
 // MOD magnitude of the largest coefficient in the above open out to prevent the mold
P3803 [template] polynomial multiplication (NTT)

Inverse polynomial:

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const int N=3e5+10,mod=998244353,G=3;
int n,pos[N];
ll a[N],b[N],c[N],invG;
ll pw(ll x,ll k){
    ll num=1;
    while(k){
        if(k&1)num=num*x%mod;
        x=x*x%mod;
        k>>=1;
    }
    return num;
}
void ntt(ll *f,int n,bool flag){
    for(int i=0;i<n;i++)if(i<pos[i])swap(f[i],f[pos[i]]);
    for(int p=2;p<=n;p<<=1){
        int len=p>>1;
        ll fir=pw((flag?G:invG),(mod-1)/p);
        for(int k=0;k<n;k+=p){
            ll bur=1;
            for(int l=k;l<len+k;l++){
                ll tt = f [l + len] * cage% mod;
                f [len + l] = ((f [l] -tT)% v + v)% v;
                f[l]=(f[l]+tt)%mod;
                bur = bur *% for mod;
            }
        }
    }
}                
void getinv(int now,ll *a,ll*b){
    if(now==1){b[0]=pw(a[0],mod-2);return;}
    getinv((now+1)>>1,a,b);
    int goal=1;
    while(goal<(now<<1))goal<<=1;
    ll invn=pw(goal,mod-2);
    for(int i=0;i<goal;i++)pos[i]=(pos[i>>1]>>1)|((i&1)?(goal>>1):0);
    for(int i=0;i<now;i++)c[i]=a[i];
    for(int i=now;i<goal;i++)c[i]=0;
    ntt(c,goal,1),ntt(b,goal,1);
    for(int i=0;i<goal;i++)b[i]=((2ll-c[i]*b[i]%mod)%mod+mod)%mod*b[i]%mod;
    ntt(b,goal,0);
    for(int i=0;i<now;i++)b[i]=b[i]*invn%mod;
    for(int i=now;i<goal;i++)b[i]=0;
}
int main () {
    scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%lld",&a[i]);
    invG=pw(G,mod-2);
    getinv(n,a,b);
    for(int i=0;i<n;i++)printf("%lld ",b[i]);
    return 0;
}
// recursive nature of each layer x ^ now modulo inverse redundant array b After each treatment should be partially emptied out of the mold.
P4238 [template] inverse polynomial multiplication

 

Some of the topics:

 


Sustained finished up, please remember your own review.

Guess you like

Origin www.cnblogs.com/chloris/p/12072717.html