多项式全家桶

跑的很慢。因为没有用什么看不懂的东西。

刚刚写完比较基本的东西,持续更新。

要是内存爆就把多点求值和快速插值干掉。

示例代码为挑战多项式,2077ms。(多项式全家桶 2077)

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
const int mod=998244353;
#define add(x,y) (x+y>=mod?x+y-mod:x+y)
#define sub(x,y) (x-y<0?x-y+mod:x-y)
namespace IO{
    int read(){
        int x=0;char ch=getchar();
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch))x=(10ll*x+ch-'0')%mod,ch=getchar();
        return x;
    }
    void print(int x){
        if(x>9)print(x/10);
        putchar(x%10+'0');
    }
}
inline int qpow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)ans=1ll*ans*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return ans;
}
namespace Math{
    int jc[600010],inv[600010],Inv[600010];
    inline int C(int n,int m){
        if(n<m||m<0)return 0;
        return 1ll*jc[n]*Inv[m]%mod*Inv[n-m]%mod;
    }
    namespace Cipolla{
        int n,I;
        struct cp{
            int r,i;
            inline cp(int a=0,int b=0){r=a;i=b;}
            inline bool operator==(const cp &s)const{return r==s.r&&i==s.i;}
            inline cp operator+(const cp &s)const{return cp{(r+s.r)%mod,(i+s.i)%mod};}
            inline cp operator-(const cp &s)const{return cp{(r-s.r+mod)%mod,(i-s.i+mod)%mod};}
            inline cp operator*(const cp &s)const{int real=(1ll*r*s.r%mod+1ll*I*i%mod*s.i%mod)%mod,imag=(1ll*r*s.i%mod+1ll*i*s.r%mod)%mod;return cp{real,imag};}
        };
        inline cp qpow(cp a,int b){
            cp ans=1;
            while(b){
                if(b&1)ans=ans*a;
                a=a*a;
                b>>=1;
            }
            return ans;
        }
        inline bool check(int x){return qpow(cp(x),(mod-1)>>1)==1;}
        inline pair<int,int> getsqrt(int n){
            int a=rand()%mod;
            while(!a||check((1ll*a*a-n+mod)%mod))a=rand()%mod;
            I=(1ll*a*a-n+mod)%mod;
            int x=qpow(cp(a,1),(mod+1)>>1).r;
            return make_pair(x,mod-x);
        }
        inline int get(int n){
            pair<int,int>ans=getsqrt(n);
            if(ans.first>ans.second)swap(ans.first,ans.second);
            return ans.first;
        }
    }
}
using namespace IO;
using namespace Math;
namespace Polynomial{
    struct poly{
        vector<int>f;
        inline poly(int val=0):f(val){}
        inline poly(const vector<int>&g):f(g){}
        inline poly(const poly&g):f(g.f){}
        inline int operator[](int p)const{return f[p];}
        inline int &operator[](int p){return f[p];}
        inline vector<int>::iterator begin(){return f.begin();}
        inline vector<int>::iterator end(){return f.end();}
        inline int size()const{return f.size();}
        inline void resize(int n){f.resize(n);}
        inline poly slice(int d)const{
            poly ret(f);ret.resize(d);
            return ret;
        }
        inline int calc(int x)const{
            int ans=0,tmp=1;
            for(int i=0;i<f.size();i++){
                ans=(ans+1ll*f[i]*tmp)%mod;
                tmp=1ll*tmp*x%mod;
            }
            return ans;
        }
        inline poly operator+(const poly &p)const{
            int d=max(size(),p.size()),mn=min(size(),p.size());
            poly ans(d);
            for(int i=0;i<mn;i++)ans[i]=add(f[i],p[i]);
            if(size()<p.size())for(int i=mn;i<d;i++)ans[i]=p[i];
            else for(int i=mn;i<d;i++)ans[i]=f[i];
            return ans;
        }
        inline poly operator-()const{
            poly ans(f);
            for(int i=0;i<f.size();i++)ans[i]=sub(0,ans[i]);
            return ans;
        }
        inline poly operator-(const poly&p)const{
            return operator+(-p);
        }
        inline friend poly operator+(poly a,int b){
            a[0]=add(a[0],b);
            return a;
        }
        inline friend poly operator+(int b,poly a){
            a[0]=add(a[0],b);
            return a;
        }
        inline friend poly operator-(poly a,int b){
            a[0]=sub(a[0],b);
            return a;
        }
        inline friend poly operator-(int b,poly a){
            return b+(-a);
        }
        inline friend poly operator*(poly a,int b){
            int n=a.size();
            for(int i=0;i<n;i++)a[i]=1ll*a[i]*b%mod;
            return a;
        }
        inline friend poly operator*(int b,poly a){
            int n=a.size();
            for(int i=0;i<n;i++)a[i]=1ll*a[i]*b%mod;
            return a;
        }
        inline poly operator<<(int d)const{
            poly ans(d+size());
            for(int i=0;i<size();i++)ans[i+d]=f[i];
            return ans;
        }
        inline poly operator>>(int d)const{
            if(d>=size())return poly(0);
            return vector<int>(f.begin()+d,f.end());
        }
        inline friend poly dao(poly p){
            int n=p.size();
            for(int i=1;i<n;i++)p[i-1]=1ll*p[i]*i%mod;p[n-1]=0;
            return p;
        }
        inline friend poly jifen(poly p){
            int n=p.size();
            for(int i=n-1;i>=1;i--)p[i]=1ll*p[i-1]*inv[i]%mod;p[0]=0;
            return p;
        }
    };
    namespace NTT{
        int wl;
        unsigned long long w[600010];
        const unsigned __int128 mod2=mod;
        inline void get(int n){
            wl=1;
            while(wl<n)wl<<=1;
        }
        inline void init(int n){
            int t=1;
            while((1<<t)<n)t++;
            t=min(t-1,21);
            w[0]=1;w[1<<t]=qpow(31,1<<21-t);inv[1]=1;
            for(int i=t;i>=1;i--)w[1<<i-1]=1ll*w[1<<i]*w[1<<i]%mod;
            for(int i=1;i<(1<<t);i++)w[i]=1ll*w[i&i-1]*w[i&-i]%mod;
            for(int i=0;i<=(1<<t);i++)w[i]=(((unsigned __int128)w[i]<<64)+mod-1)/mod;
            for(int i=2;i<=n;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
            jc[0]=Inv[0]=1;
            for(int i=1;i<=n;i++)jc[i]=1ll*jc[i-1]*i%mod,Inv[i]=1ll*Inv[i-1]*inv[i]%mod;
        }
        inline void DIF(poly &a){
            int n=a.size();
            for(int mid=n>>1;mid;mid>>=1){
                for(int i=0,k=0;i<n;i+=mid<<1,k++){
                    for(int j=0;j<mid;j++){
                        int x=a[i+j],y=(unsigned)a[i+j+mid]*w[k]*mod2>>64;
                        a[i+j]=add(x,y);a[i+j+mid]=sub(x,y);
                    }
                }
            }
        }
        inline void DIT(poly &a){
            int n=a.size();
            for(int mid=1;mid<n;mid<<=1){
                for(int i=0,k=0;i<n;i+=mid<<1,k++){
                    for(int j=0;j<mid;j++){
                        int x=a[i+j],y=a[i+j+mid];
                        a[i+j]=add(x,y);a[i+j+mid]=sub(x,y);
                        a[i+j+mid]=(unsigned)a[i+j+mid]*w[k]*mod2>>64;
                    }
                }
            }
            for(int i=1;i<=(n-1)>>1;i++)swap(a[i],a[n-i]);
            int inv=qpow(n,mod-2);
            for(int i=0;i<n;i++)a[i]=1ll*a[i]*inv%mod;
        }
    }
    using namespace NTT;
    inline poly operator*(poly f,poly g){
        if(max(f.size(),g.size())<=128){
            poly ret(f.size()+g.size()-1);
            for(int i=0;i<f.size();i++){
                for(int j=0;j<g.size();j++){
                    ret[i+j]=(ret[i+j]+1ll*f[i]*g[j])%mod;
                }
            }
            return ret;
        }
        int n=f.size(),m=g.size();
        get(n+m);
        f.resize(wl);g.resize(wl);
        DIF(f);DIF(g);
        for(int i=0;i<wl;i++)f[i]=1ll*f[i]*g[i]%mod;
        DIT(f);
        return f.slice(n+m-1);
    }
    inline poly operator^(poly f,poly g){
        reverse(f.begin(),f.end());
        poly ans=(f*g).slice(f.size());
        reverse(ans.begin(),ans.end());
        return ans;
    }
    inline poly getinv(poly f){
        int n=f.size();get(n);
        f.resize(wl);
        poly g(wl),tmp,ret;
        g[0]=qpow(f[0],mod-2);
        for(int len=2;len<=wl;len<<=1){
            tmp.resize(len);ret.resize(len);
            for(int i=0;i<len;i++)tmp[i]=f[i];
            for(int i=0;i<(len>>1);i++)ret[i]=g[i];
            DIF(tmp);DIF(ret);
            for(int i=0;i<len;i++)tmp[i]=1ll*tmp[i]*ret[i]%mod;
            DIT(tmp);
            for(int i=1;i<(len>>1);i++)tmp[i]=0;tmp[0]=mod-1;
            DIF(tmp);
            for(int i=0;i<len;i++)ret[i]=1ll*tmp[i]*ret[i]%mod;
            DIT(ret);
            for(int i=len>>1;i<len;i++)g[i]=sub(0,ret[i]);
        }
        return g.slice(n);
    }
    inline poly operator/(poly a,poly b){
        int n=a.size(),m=b.size();
        poly q(a),f(b);
        reverse(q.begin(),q.end());
        reverse(f.begin(),f.end());
        f.resize(n-m+1);f=getinv(f);
        q=q*f;q.resize(n-m+1);reverse(q.begin(),q.end());
        return q;
    }
    inline poly operator%(poly a,poly b){
        int n=a.size(),m=b.size();
        poly q=a/b;b=b*q;
        poly r=a-b;
        return r.slice(m-1);
    }
    inline pair<poly,poly> quo(poly a,poly b){
        int n=a.size(),m=b.size();
        poly q=a/b;
        b=b*q;
        poly r=a-b;r.resize(m-1);
        return make_pair(q,r);
    }
    namespace CDQ{
        poly F[20][8],G[20][8];
        inline void brute(poly &f,poly &g,int l,int r,void relax(poly &f,poly &g,int i)){
            relax(f,g,l);
            for(int i=l+1;i<=r;i++){
                for(int j=l;j<i;j++){
                    int x=1ll*f[j]*g[i-j]%mod;
                    f[i]=add(f[i],x);
                }
                relax(f,g,i);
            }
        }
        void cdq(int l,int r,int dep,poly &f,poly &g,void relax(poly &f,poly &g,int i)){
            if(r-l+1<=32){
                brute(f,g,l,r,relax);return;
            }
            if(l>=r)return;
            int d=1<<((dep-1)*3);
            poly tmp(d<<1);
            for(int i=0;;i++){
                int L=l+i*d,R=min(r,L+d-1);
                if(i){
                    for(int j=0;j<(d<<1);j++)tmp[j]=0;
                    for(int j=0;j<i;j++){
                        for(int k=0;k<(d<<1);k++){
                            int x=1ll*F[dep][j][k]*G[dep][i-j][k]%mod;
                            tmp[k]=add(tmp[k],x);
                        }
                    }
                    DIT(tmp);
                    for(int i=L;i<=R;i++)f[i]=add(f[i],tmp[i-L+d]);
                }
                cdq(L,R,dep-1,f,g,relax);
                if(R==r)return;
                for(int j=0;j<(d<<1);j++)F[dep][i][j]=0;
                for(int j=L;j<=R;j++)F[dep][i][j-L]=f[j];
                DIF(F[dep][i]);
            }
        }
        inline void solve(poly &f,poly &g,int n,void relax(poly &f,poly &g,int i)){
            if(n<=128){
                brute(f,g,0,n-1,relax);return;
            }
            int len=1,dep=0;
            while(len<n)len<<=3,dep++;len>>=3;
            for(int i=1;i<=dep;i++){
                int d=1<<((i-1)*3),mn=min((n-1)/d,7);
                for(int j=1;j<=mn;j++){
                    int l=(j-1)*d+1,r=min(n-1,(j+1)*d-1);
                    F[i][j-1].resize(d<<1);G[i][j].resize(d<<1);
                    for(int k=0;k<(d<<1);k++)G[i][j][k]=0;
                    for(int k=l;k<=r;k++)G[i][j][k-l+1]=g[k];
                    DIF(G[i][j]);
                }
            }
            cdq(0,n-1,dep,f,g,relax);
        }
    }
    using namespace CDQ;
    inline void relaxln(poly&f,poly &g,int i){
        if(!i)f[i]=0;
        else f[i]=(1ll*i*g[i]-f[i]+mod)%mod;
    }
    inline void relaxexp(poly &f,poly &g,int i){
        if(!i)f[i]=1;
        else f[i]=1ll*f[i]*inv[i]%mod;
    }
    inline poly ln(poly f){
        int n=f.size();
        poly g(n);
        solve(g,f,n,relaxln);
        g[0]=0;
        for(int i=1;i<n;i++)g[i]=1ll*g[i]*inv[i]%mod;
        return g;
    }
    inline poly exp(poly f){
        int n=f.size();
        for(int i=0;i<n;i++)f[i]=1ll*f[i]*i%mod;
        poly g(n);
        solve(g,f,n,relaxexp);
        return g;
    }
    inline poly qpow(poly f,int k){
        int n=f.size();
        f=ln(f);
        for(int i=0;i<n;i++)f[i]=1ll*k*f[i]%mod;
        f=exp(f);
        return f;
    }
    inline poly qpow(poly f,int k1,int k2,int k3){
        int n=f.size();
        poly g(n);
        if(f[0]==0&&k3>=n)return g;
        int pos;
        for(int i=0;i<n;i++){
            if(f[i]){
                pos=i;break;
            }
        }
        if(1ll*pos*k1>=n)return g;
        int inv=::qpow(f[pos],mod-2),p=::qpow(f[pos],k2);
        for(int i=0;i<n-pos;i++)f[i]=1ll*f[i+pos]*inv%mod;
        for(int i=n-pos;i<n;i++)f[i]=0;
        f=ln(f);
        for(int i=0;i<n;i++)f[i]=1ll*f[i]*k1%mod;
        f=exp(f);
        pos*=k1;
        for(int i=n-1;i>=pos;i--)g[i]=1ll*f[i-pos]*p%mod;
        return g;
    }
    inline poly sqrt(poly f,int tp=1){
        int n=f.size();get(n);
        f.resize(wl);
        poly g(wl),g2(wl),h(wl),tmp,ret(1),ans;
        g[0]=g2[0]=Cipolla::get(f[0]);h[0]=::qpow(g[0],mod-2);
        for(int len=2;len<=wl;len<<=1){
            ans.resize(len);tmp.resize(len);
            for(int i=0;i<(len>>1);i++)tmp[i]=h[i],ret[i]=1ll*g2[i]*g2[i]%mod;
            DIT(ret);
            for(int i=0;i<(len>>1);i++)ans[i+(len>>1)]=sub(sub(ret[i],f[i]),f[i+(len>>1)]),ans[i]=0;
            DIF(ans);DIF(tmp);
            for(int i=0;i<len;i++)ans[i]=1ll*ans[i]*tmp[i]%mod*inv[2]%mod;
            DIT(ans);
            for(int i=len>>1;i<len;i++)g[i]=sub(0,ans[i]);
            if(len!=wl||tp==-1){
                ret.resize(len);
                for(int i=0;i<len;i++)ret[i]=g[i];
                DIF(ret);
                for(int i=0;i<len;i++)g2[i]=ret[i],ret[i]=1ll*ret[i]*tmp[i]%mod;
                DIT(ret);
                for(int i=1;i<(len>>1);i++)ret[i]=0;ret[0]=mod-1;
                DIF(ret);
                for(int i=0;i<len;i++)ret[i]=1ll*ret[i]*tmp[i]%mod;
                DIT(ret);
                for(int i=len>>1;i<len;i++)h[i]=sub(0,ret[i]);
            }
        }
        if(tp==1)return g.slice(n);
        else return h.slice(n);
    }
    inline poly move(poly a,int k){
        int n=a.size();get(n<<1);
        poly b(n);
        for(int i=0,pw=1;i<n;i++,pw=1ll*pw*k%mod)a[i]=1ll*a[i]*jc[i]%mod,b[i]=1ll*pw*Inv[i]%mod;
        reverse(a.begin(),a.end());
        a=a*b;a.resize(n);
        reverse(a.begin(),a.end());
        for(int i=0;i<n;i++)a[i]=1ll*a[i]*Inv[i]%mod;
        return a;
    }
    inline poly movepoint(poly f,int m){
        int n=f.size()-1;
        poly g(n<<1|1);
        static int mjc[600010],minv[600010];mjc[0]=minv[0]=1;
        for(int i=1;i<=2*n+1;i++)mjc[i]=1ll*mjc[i-1]*(m-n-1+i)%mod;
        minv[n<<1|1]=::qpow(mjc[n<<1|1],mod-2);
        for(int i=n<<1;i>=1;i--)minv[i]=1ll*minv[i+1]*(m-n+i)%mod;
        for(int i=0;i<=n;i++){
            f[i]=1ll*f[i]*Inv[i]%mod*Inv[n-i]%mod;
            if(n-i&1)f[i]=sub(0,f[i]);
        }
        for(int i=0;i<=(n<<1);i++)g[i]=1ll*minv[i+1]*mjc[i]%mod;
        get(n+1<<1);
        f.resize(wl);g.resize(wl);DIF(f);DIF(g);
        for(int i=0;i<wl;i++)f[i]=1ll*f[i]*g[i]%mod;DIT(f);
        for(int i=n;i<=(n<<1);i++)f[i-n]=1ll*mjc[i+1]*minv[i-n]%mod*f[i]%mod;
        return f;
    }
        namespace Multipoint{
        poly F[20],G[400010];
        #define lson rt<<1
        #define rson rt<<1|1
        void build(int rt,int l,int r,poly&a){
            if(l==r){
                G[rt].resize(2);
                G[rt][0]=1;G[rt][1]=sub(0,a[l]);
                return;
            }
            int mid=(l+r)>>1;
            build(lson,l,mid,a);build(rson,mid+1,r,a);
            G[rt]=G[lson]*G[rson];
        }
        void query(int rt,int l,int r,int dep,poly &a){
            F[dep].resize(r-l+2);
            if(l==r){
                a[l]=F[dep][0];return;
            }
            int mid=(l+r)>>1;
            F[dep+1]=F[dep]^G[rson];
            query(lson,l,mid,dep+1,a);
            F[dep+1]=F[dep]^G[lson];
            query(rson,mid+1,r,dep+1,a);
        }
        poly multipoint(poly a,poly b,int n,int m){
            n=max(n,m+1);m=n-1;
            a.resize(n);b.resize(m+1);
            build(1,1,m,b);
            poly inv=getinv(G[1]);
            reverse(inv.begin(),inv.end());
            poly tmp=a*inv;
            F[0].resize(m+1);
            for(int i=n;i<n+m;i++)F[0][i-n]=tmp[i];
            poly ans(m+1);
            query(1,1,m,0,ans);
            for(int i=1;i<=m;i++)ans[i]=(1ll*ans[i]*b[i]+a[0])%mod;
            return ans;
        }
        #undef lson
        #undef rson
    }
    using Multipoint::multipoint;
    namespace Multipoly{
        #define lson rt<<1
        #define rson rt<<1|1
        poly F[800010],G[800010];
        void build(int rt,int l,int r,poly&a){
            if(l==r){
                G[rt].resize(2);
                G[rt][0]=sub(0,a[l]);G[rt][1]=1;
                return;
            }
            int mid=(l+r)>>1;
            build(lson,l,mid,a);build(rson,mid+1,r,a);
            G[rt]=G[lson]*G[rson];
        }
        void query(int rt,int l,int r,poly&y){
            if(l==r){
                F[rt].resize(2);
                F[rt][0]=y[l];return;
            }
            int mid=(l+r)>>1;
            query(lson,l,mid,y);query(rson,mid+1,r,y);
            F[rt]=F[lson]*G[rson]+F[rson]*G[lson];
        }
        poly getpoly(int n,poly x,poly y){
            build(1,1,n,x);
            poly tmp(n+1),ans(n);
            for(int i=0;i<=n;i++)tmp[i]=G[1][i];
            tmp=dao(tmp);
            poly ret=multipoint(tmp,x,n+1,n);
            for(int i=1;i<=n;i++)y[i]=1ll*y[i]*::qpow(ret[i],mod-2)%mod;
            query(1,1,n,y);
            for(int i=0;i<n;i++)ans[i]=F[1][i];
            return ans;
        }
        #undef lson
        #undef rson
    }
    using Multipoly::getpoly;
    namespace Downpower{
        inline void FDT(poly &f,int tp){
            int n=f.size();
            poly g(n);
            for(int i=0;i<n;i++){
                if((tp^1)&&(i&1))g[i]=mod-Inv[i];
                else g[i]=Inv[i];
            }
            f=(f*g).slice(n);
        }
        inline poly mul(poly f,poly g){
            int n=f.size(),m=g.size();
            f.resize(n+m-1);g.resize(n+m-1);
            FDT(f,1);FDT(g,1);
            for(int i=0;i<n+m-1;i++)f[i]=1ll*f[i]*g[i]%mod*jc[i]%mod;
            FDT(f,-1);
            return f;
        }
        inline poly SimpToDown(poly f){
            int n=f.size();
            poly g(n+1);
            for(int i=1;i<=n;i++)g[i]=i-1;
            f=multipoint(f,g,n+1,n)>>1;
            for(int i=0;i<n;i++)f[i]=1ll*f[i]*Inv[i]%mod;
            FDT(f,-1);
            return f;
        }
        pair<poly,poly> solveDownToSimp(int l,int r,poly &f){
            if(l==r){
                if(!l){
                    poly g(1);g[0]=f[0];
                    return make_pair(g,g);
                }
                else{
                    poly g(2);int ret=1ll*f[l]*::qpow(f[l-1],mod-2)%mod;
                    g[0]=1ll*ret*(1-l+mod)%mod;g[1]=ret;
                    return make_pair(g,g);
                }
            }
            int mid=(l+r)>>1;
            pair<poly,poly> ans1=solveDownToSimp(l,mid,f),ans2=solveDownToSimp(mid+1,r,f);
            return make_pair(ans1.first*ans2.first,ans1.first*ans2.second+ans1.second);
        }
        inline poly DownToSimp(poly f){
            int n=f.size();
            return solveDownToSimp(0,n-1,f).second;
        }
    }
    using namespace Downpower;
    inline poly chirpz(poly f,int k,int m){
        int n=f.size();
        static int c[2100010],invc[2100010];
        c[0]=invc[0]=1;c[1]=k;invc[1]=::qpow(c[1],mod-2);
        for(int i=2;i<=n+m;i++)c[i]=1ll*c[i-1]*c[1]%mod,invc[i]=1ll*invc[i-1]*invc[1]%mod;
        poly g(n+m+1);g[0]=1;
        for(int i=1;i<=n+m;i++){
            c[i]=1ll*c[i]*c[i-1]%mod;invc[i]=1ll*invc[i]*invc[i-1]%mod;
            g[i]=c[i-1];
        }
        for(int i=0;i<n;i++){
            f[i]=1ll*f[i]*(i?invc[i-1]:1)%mod;
        }
        f.resize(n+1);
        reverse(f.begin(),f.end());
        get(n+m);
        f.resize(wl);g.resize(wl);
        DIF(f);DIF(g);
        for(int i=0;i<wl;i++)f[i]=1ll*f[i]*g[i]%mod;
        DIT(f);
        for(int i=0;i<m;i++)f[i]=1ll*f[i+n]*(i?invc[i-1]:1)%mod;
        return f.slice(m);
    }
    inline poly sin(poly f){
        const int I=::qpow(3,(mod-1)>>2);
        return (exp(I*f)-exp((mod-I)*f))*::qpow(2ll*I%mod,mod-2);
    }
    inline poly asin(poly f){
        int n=f.size();
        return jifen((dao(f)*sqrt(1-(f*f).slice(n),-1)).slice(n));
    }
    inline poly cos(poly f){
        const int I=::qpow(3,(mod-1)>>2);
        return (exp(I*f)+exp((mod-I)*f))*(mod+1>>1);
    }
    inline poly acos(poly f){
        return -asin(f);
    }
    inline poly tan(poly f){
        int n=f.size();
        return (sin(f)*getinv(cos(f))).slice(n);
    }
    inline poly atan(poly f){
        int n=f.size();
        return jifen((dao(f)*getinv(1+(f*f).slice(n))).slice(n));
    }
}
using namespace Polynomial;
int n,k;
int main(){
    n=read()+1;k=read();init(n<<1);
    poly a(n);
    for(int i=0;i<n;i++)a[i]=read();
    a=dao(qpow(1+ln(2+a-a[0]-exp(jifen(sqrt(a,-1)))),k));
    for(int i=0;i<n-1;i++)print(a[i]),putchar(' ');puts("");
    return 0;
}
posted @ 2023-05-15 19:30  gtm1514  阅读(109)  评论(5编辑  收藏  举报