結果

問題 No.2583 Differential Equation (Enhanced version)
ユーザー tko919tko919
提出日時 2023-12-13 06:48:34
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 2,578 ms / 10,000 ms
コード長 23,468 bytes
コンパイル時間 3,244 ms
コンパイル使用メモリ 230,832 KB
実行使用メモリ 32,572 KB
最終ジャッジ日時 2024-09-27 05:12:55
合計ジャッジ時間 32,755 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,376 KB
testcase_02 AC 2 ms
5,376 KB
testcase_03 AC 11 ms
5,376 KB
testcase_04 AC 6 ms
5,376 KB
testcase_05 AC 11 ms
5,376 KB
testcase_06 AC 2 ms
5,376 KB
testcase_07 AC 9 ms
5,376 KB
testcase_08 AC 6 ms
5,376 KB
testcase_09 AC 17 ms
5,376 KB
testcase_10 AC 7 ms
5,376 KB
testcase_11 AC 10 ms
5,376 KB
testcase_12 AC 3 ms
5,376 KB
testcase_13 AC 1,282 ms
18,260 KB
testcase_14 AC 170 ms
5,732 KB
testcase_15 AC 388 ms
8,424 KB
testcase_16 AC 1,629 ms
22,116 KB
testcase_17 AC 89 ms
5,376 KB
testcase_18 AC 786 ms
12,236 KB
testcase_19 AC 636 ms
11,376 KB
testcase_20 AC 575 ms
10,464 KB
testcase_21 AC 7 ms
5,376 KB
testcase_22 AC 1,371 ms
18,940 KB
testcase_23 AC 2,562 ms
32,324 KB
testcase_24 AC 2,537 ms
32,572 KB
testcase_25 AC 2,578 ms
32,456 KB
testcase_26 AC 2,530 ms
32,264 KB
testcase_27 AC 2,509 ms
32,320 KB
testcase_28 AC 329 ms
7,924 KB
testcase_29 AC 2,288 ms
31,460 KB
testcase_30 AC 287 ms
7,112 KB
testcase_31 AC 3 ms
5,376 KB
testcase_32 AC 3 ms
5,376 KB
testcase_33 AC 2 ms
5,376 KB
testcase_34 AC 2 ms
5,376 KB
testcase_35 AC 5 ms
5,376 KB
testcase_36 AC 2 ms
5,376 KB
testcase_37 AC 5 ms
5,376 KB
testcase_38 AC 2,517 ms
32,304 KB
testcase_39 AC 2,510 ms
32,456 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(v) (v).begin(),(v).end()
#define UNIQUE(v) sort(ALL(v)),(v).erase(unique(ALL(v)),(v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v,x) int(lower_bound(ALL(v),(x))-(v).begin())
#define UB(v,x) int(upper_bound(ALL(v),(x))-(v).begin())

using ll=long long int;
using ull=unsigned long long;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
template<typename T,typename U>T ceil(T x,U y){assert(y!=0); if(y<0)x=-x,y=-y; return (x>0?(x+y-1)/y:x/y);}
template<typename T,typename U>T floor(T x,U y){assert(y!=0); if(y<0)x=-x,y=-y; return (x>0?x/y:(x-y+1)/y);}
template<typename T>int popcnt(T x){return __builtin_popcountll(x);}
template<typename T>int topbit(T x){return (x==0?-1:63-__builtin_clzll(x));}
template<typename T>int lowbit(T x){return (x==0?-1:__builtin_ctzll(x));}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>

class FastIO{
    static constexpr int L=1<<16;
    char rdbuf[L];
    int rdLeft=0,rdRight=0;
    inline void reload(){
        int len=rdRight-rdLeft;
        memmove(rdbuf,rdbuf+rdLeft,len);
        rdLeft=0,rdRight=len;
        rdRight+=fread(rdbuf+len,1,L-len,stdin);
    }
    inline bool skip(){
        for(;;){
            while(rdLeft!=rdRight and rdbuf[rdLeft]<=' ')rdLeft++;
            if(rdLeft==rdRight){
                reload();
                if(rdLeft==rdRight)return false;
            }
            else break;
        }
        return true;
    }
    template<typename T,enable_if_t<is_integral<T>::value,int> =0>inline bool _read(T& x){
        if(!skip())return false;
        if(rdLeft+20>=rdRight)reload();
        bool neg=false;
        if(rdbuf[rdLeft]=='-'){
            neg=true;
            rdLeft++;
        }
        x=0;
        while(rdbuf[rdLeft]>='0' and rdLeft<rdRight){
            x=x*10+(neg?-(rdbuf[rdLeft++]^48):(rdbuf[rdLeft++]^48));
        }
        return true;
    }
    inline bool _read(__int128_t& x){
        if(!skip())return false;
        if(rdLeft+40>=rdRight)reload();
        bool neg=false;
        if(rdbuf[rdLeft]=='-'){
            neg=true;
            rdLeft++;
        }
        x=0;
        while(rdbuf[rdLeft]>='0' and rdLeft<rdRight){
            x=x*10+(neg?-(rdbuf[rdLeft++]^48):(rdbuf[rdLeft++]^48));
        }
        return true;
    }
    inline bool _read(__uint128_t& x){
        if(!skip())return false;
        if(rdLeft+40>=rdRight)reload();
        x=0;
        while(rdbuf[rdLeft]>='0' and rdLeft<rdRight){
            x=x*10+(rdbuf[rdLeft++]^48);
        }
        return true;
    }
    template<typename T,enable_if_t<is_floating_point<T>::value,int> =0>inline bool _read(T& x){
        if(!skip())return false;
        if(rdLeft+20>=rdRight)reload();
        bool neg=false;
        if(rdbuf[rdLeft]=='-'){
            neg=true;
            rdLeft++;
        }
        x=0;
        while(rdbuf[rdLeft]>='0' and rdbuf[rdLeft]<='9' and rdLeft<rdRight){
            x=x*10+(rdbuf[rdLeft++]^48);
        }
        if(rdbuf[rdLeft]!='.')return true;
        rdLeft++;
        T base=.1;
        while(rdbuf[rdLeft]>='0' and rdbuf[rdLeft]<='9' and rdLeft<rdRight){
            x+=base*(rdbuf[rdLeft++]^48);
            base*=.1;
        }
        if(neg)x=-x;
        return true;
    }
    inline bool _read(char& x){
        if(!skip())return false;
        if(rdLeft+1>=rdRight)reload();
        x=rdbuf[rdLeft++];
        return true;
    }
    inline bool _read(string& x){
        if(!skip())return false;
        for(;;){
            int pos=rdLeft;
            while(pos<rdRight and rdbuf[pos]>' ')pos++;
            x.append(rdbuf+rdLeft,pos-rdLeft);
            if(rdLeft==pos)break;
            rdLeft=pos;
            if(rdLeft==rdRight)reload();
            else break;
        }
        return true;
    }
    template<typename T>inline bool _read(vector<T>& v){
        for(auto& x:v){
            if(!_read(x))return false;
        }
        return true;
    }

    char wtbuf[L],tmp[50];
    int wtRight=0;
    inline void _write(const char& x){
        if(wtRight>L-32)flush();
        wtbuf[wtRight++]=x;
    }
    inline void _write(const string& x){
        for(auto& c:x)_write(c);
    }
    template<typename T,enable_if_t<is_integral<T>::value,int> =0>inline void _write(T x){
        if(wtRight>L-32)flush();
        if(x==0){
            _write('0');
            return;
        }
        else if(x<0){
            _write('-');
            if (__builtin_expect(x == std::numeric_limits<T>::min(), 0)) {
                switch (sizeof(x)) {
                case 2: _write("32768"); return;
                case 4: _write("2147483648"); return;
                case 8: _write("9223372036854775808"); return;
                }
            }
            x=-x;
        }
        int pos=0;
        while(x!=0){
            tmp[pos++]=char((x%10)|48);
            x/=10;
        }
        rep(i,0,pos)wtbuf[wtRight+i]=tmp[pos-1-i];
        wtRight+=pos;
    }
    inline void _write(__int128_t x){
        if(wtRight>L-40)flush();
        if(x==0){
            _write('0');
            return;
        }
        else if(x<0){
            _write('-');
            x=-x;
        }
        int pos=0;
        while(x!=0){
            tmp[pos++]=char((x%10)|48);
            x/=10;
        }
        rep(i,0,pos)wtbuf[wtRight+i]=tmp[pos-1-i];
        wtRight+=pos;
    }
    inline void _write(__uint128_t x){
        if(wtRight>L-40)flush();
        if(x==0){
            _write('0');
            return;
        }
        int pos=0;
        while(x!=0){
            tmp[pos++]=char((x%10)|48);
            x/=10;
        }
        rep(i,0,pos)wtbuf[wtRight+i]=tmp[pos-1-i];
        wtRight+=pos;
    }
    inline void _write(double x){
        ostringstream oss;
        oss << fixed << setprecision(15) << double(x);
        string s = oss.str();
        _write(s);
    }
    template<typename T>inline void _write(const vector<T>& v){
        rep(i,0,v.size()){
            if(i)_write(' ');
            _write(v[i]);
        }
    }
public:
    FastIO(){}
    ~FastIO(){flush();}
    inline void read(){}
    template <typename Head, typename... Tail>inline void read(Head& head,Tail&... tail){
        assert(_read(head));
        read(tail...); 
    }
    template<bool ln=true,bool space=false>inline void write(){if(ln)_write('\n');}
    template <bool ln=true,bool space=false,typename Head, typename... Tail>inline void write(const Head& head,const Tail&... tail){
        _write(head);
        write<ln,true>(tail...); 
        if(space)_write(' ');
    }
    inline void flush(){
        fwrite(wtbuf,1,wtRight,stdout);
        wtRight=0;
    }
};

/**
 * @brief Fast IO
 */
#line 3 "sol.cpp"

#line 2 "library/Math/modint.hpp"

template<int mod=1000000007>struct fp {
    int v;
    static constexpr int get_mod(){return mod;}
    int inv() const{
        int tmp,a=v,b=mod,x=1,y=0;
        while(b)tmp=a/b,a-=tmp*b,swap(a,b),x-=tmp*y,swap(x,y);
        if(x<0){x+=mod;} return x;
    }
    fp(ll x=0){init(x%mod+mod);}
    fp& init(ll x){v=(x<mod?x:x-mod); return *this;}
    fp operator-()const{return fp()-*this;}
    fp pow(ll t){assert(t>=0); fp res=1,b=*this; while(t){if(t&1)res*=b;b*=b;t>>=1;} return res;}
    fp& operator+=(const fp& x){return init(v+x.v);}
    fp& operator-=(const fp& x){return init(v+mod-x.v);}
    fp& operator*=(const fp& x){v=ll(v)*x.v%mod; return *this;}
    fp& operator/=(const fp& x){v=ll(v)*x.inv()%mod; return *this;}
    fp operator+(const fp& x)const{return fp(*this)+=x;}
    fp operator-(const fp& x)const{return fp(*this)-=x;}
    fp operator*(const fp& x)const{return fp(*this)*=x;}
    fp operator/(const fp& x)const{return fp(*this)/=x;}
    bool operator==(const fp& x)const{return v==x.v;}
    bool operator!=(const fp& x)const{return v!=x.v;}
    friend istream& operator>>(istream& is,fp& x){return is>>x.v;}
    friend ostream& operator<<(ostream& os,const fp& x){return os<<x.v;}
};

template<typename T>T Inv(ll n){
    static const int md=T::get_mod();
    static vector<T> buf({0,1});
    assert(n>0);
    n%=md;
    while(SZ(buf)<=n){
        int k=SZ(buf),q=(md+k-1)/k;
        buf.push_back(buf[k*q-md]*q);
    }
    return buf[n];
}

template<typename T>T Fact(ll n,bool inv=0){
    static const int md=T::get_mod();
    static vector<T> buf({1,1}),ibuf({1,1});
    assert(n>=0 and n<md);
    while(SZ(buf)<=n){
        buf.push_back(buf.back()*SZ(buf));
        ibuf.push_back(ibuf.back()*Inv<T>(SZ(ibuf)));
    }
    return inv?ibuf[n]:buf[n];
}

template<typename T>T nPr(int n,int r,bool inv=0){if(n<0||n<r||r<0)return 0; return Fact<T>(n,inv)*Fact<T>(n-r,inv^1);}
template<typename T>T nCr(int n,int r,bool inv=0){if(n<0||n<r||r<0)return 0; return Fact<T>(n,inv)*Fact<T>(r,inv^1)*Fact<T>(n-r,inv^1);}
template<typename T>T nHr(int n,int r,bool inv=0){return nCr<T>(n+r-1,r,inv);}

/**
 * @brief Modint
 */
#line 2 "library/FPS/fps.hpp"

template<typename T>struct Poly:vector<T>{
    Poly(int n=0){this->assign(n,T());}
    Poly(const initializer_list<T> f):vector<T>::vector(f){}
    Poly(const vector<T>& f){this->assign(ALL(f));}
    T eval(const T& x){
        T res;
        for(int i=this->size()-1;i>=0;i--)res*=x,res+=this->at(i);
        return res;
    }
    Poly rev()const{Poly res=*this; reverse(ALL(res)); return res;}
    void shrink(){while(!this->empty() and this->back()==0)this->pop_back();}
    Poly operator>>(int sz)const{
        if((int)this->size()<=sz)return {};
        Poly ret(*this);
        ret.erase(ret.begin(),ret.begin()+sz);
        return ret;
    }
    Poly operator<<(int sz)const{
        Poly ret(*this);
        ret.insert(ret.begin(),sz,T(0));
        return ret;
    }
    vector<T> mult(const vector<T>& a,const vector<T>& b,bool same=0)const{
        if(a.empty() or b.empty())return vector<T>();
        int n=a.size()+b.size()-1,m=1<<__lg(n*2-1);
        vector<T> res(m);
        rep(i,0,a.size())res[i]=a[i];
        NTT(res,0);
        if(same)rep(i,0,m)res[i]*=res[i];
        else{
            vector<T> c(m);
            rep(i,0,b.size())c[i]=b[i];
            NTT(c,0);
            rep(i,0,m)res[i]*=c[i];
        }
        NTT(res,1);
        res.resize(n);
        return res;
    }
    Poly square()const{return Poly(mult(*this,*this,1));}
    Poly operator-()const{return Poly()-*this;}
    Poly operator+(const Poly& g)const{return Poly(*this)+=g;}
    Poly operator+(const T& g)const{return Poly(*this)+=g;}
    Poly operator-(const Poly& g)const{return Poly(*this)-=g;}
    Poly operator-(const T& g)const{return Poly(*this)-=g;}
    Poly operator*(const Poly& g)const{return Poly(*this)*=g;}
    Poly operator*(const T& g)const{return Poly(*this)*=g;}
    Poly operator/(const Poly& g)const{return Poly(*this)/=g;}
    Poly operator/(const T& g)const{return Poly(*this)/=g;}
    Poly operator%(const Poly& g)const{return Poly(*this)%=g;}
    pair<Poly,Poly> divmod(const Poly& g)const{
        Poly q=*this/g,r=*this-g*q;
        r.shrink();
        return {q,r};
    }
    Poly& operator+=(const Poly& g){
        if(g.size()>this->size())this->resize(g.size());
        rep(i,0,g.size()){(*this)[i]+=g[i];} return *this;
    }
    Poly& operator+=(const T& g){
        if(this->empty())this->push_back(0);
        (*this)[0]+=g; return *this;
    }
    Poly& operator-=(const Poly& g){
        if(g.size()>this->size())this->resize(g.size());
        rep(i,0,g.size()){(*this)[i]-=g[i];} return *this;
    }
    Poly& operator-=(const T& g){
        if(this->empty())this->push_back(0);
        (*this)[0]-=g; return *this;
    }
    Poly& operator*=(const Poly& g){
        *this=mult(*this,g,0);
        return *this;
    }
    Poly& operator*=(const T& g){
        rep(i,0,this->size())(*this)[i]*=g;
        return *this;
    }
    Poly& operator/=(const Poly& g){
        if(g.size()>this->size()){
            this->clear(); return *this;
        }
        Poly g2=g;
        reverse(ALL(*this));
        reverse(ALL(g2));
        int n=this->size()-g2.size()+1;
        this->resize(n); g2.resize(n);
        *this*=g2.inv(); this->resize(n); 
        reverse(ALL(*this));
        shrink();
        return *this;
    }
    Poly& operator/=(const T& g){
        rep(i,0,this->size())(*this)[i]/=g;
        return *this;
    }
    Poly& operator%=(const Poly& g){*this-=*this/g*g; shrink(); return *this;}
    Poly diff()const{
        Poly res(this->size()-1);
        rep(i,0,res.size())res[i]=(*this)[i+1]*(i+1);
        return res;
    }
    Poly inte()const{
        Poly res(this->size()+1);
        for(int i=res.size()-1;i;i--)res[i]=(*this)[i-1]/i;
        return res;
    }
    Poly log()const{
        assert(this->front()==1); const int n=this->size();
        Poly res=diff()*inv(); res=res.inte(); 
        res.resize(n); return res;
    }
    Poly shift(const int& c)const{
        const int n=this->size();
        Poly res=*this,g(n); g[0]=1; rep(i,1,n)g[i]=g[i-1]*c/i;
        vector<T> fact(n,1);
        rep(i,0,n){
            if(i)fact[i]=fact[i-1]*i;
            res[i]*=fact[i];
        }
        res=res.rev();
        res*=g;
        res.resize(n);
        res=res.rev();
        rep(i,0,n)res[i]/=fact[i];
        return res;
    }
    Poly inv()const{
        const int n=this->size();
        Poly res(1); res.front()=T(1)/this->front();
        for(int k=1;k<n;k<<=1){
            Poly f(k*2),g(k*2);
            rep(i,0,min(n,k*2))f[i]=(*this)[i];
            rep(i,0,k)g[i]=res[i];
            NTT(f,0);
            NTT(g,0);
            rep(i,0,k*2)f[i]*=g[i];
            NTT(f,1);
            rep(i,0,k){f[i]=0; f[i+k]=-f[i+k];}
            NTT(f,0);
            rep(i,0,k*2)f[i]*=g[i];
            NTT(f,1);
            rep(i,0,k)f[i]=res[i];
            swap(res,f);
        } res.resize(n); return res;
    }
    Poly exp()const{
        const int n=this->size();
        if(n==1)return Poly({T(1)});
        Poly b(2),c(1),z1,z2(2);
        b[0]=c[0]=z2[0]=z2[1]=1; b[1]=(*this)[1];
        for(int k=2;k<n;k<<=1){
            Poly y=b;
            y.resize(k*2);
            NTT(y,0);
            z1=z2;
            Poly z(k);
            rep(i,0,k)z[i]=y[i]*z1[i];
            NTT(z,1);
            rep(i,0,k>>1)z[i]=0;
            NTT(z,0);
            rep(i,0,k)z[i]*=-z1[i];
            NTT(z,1);
            c.insert(c.end(),z.begin()+(k>>1),z.end());
            z2=c;
            z2.resize(k*2);
            NTT(z2,0);
            Poly x=*this;
            x.resize(k);
            x=x.diff();x.resize(k);
            NTT(x,0);
            rep(i,0,k)x[i]*=y[i];
            NTT(x,1);
            Poly bb=b.diff();
            rep(i,0,k-1)x[i]-=bb[i];
            x.resize(k*2);
            rep(i,0,k-1){x[k+i]=x[i]; x[i]=0;}
            NTT(x,0);
            rep(i,0,k*2)x[i]*=z2[i];
            NTT(x,1);
            x.pop_back();
            x=x.inte();
            rep(i,k,min(n,k*2))x[i]+=(*this)[i];
            rep(i,0,k)x[i]=0;
            NTT(x,0);
            rep(i,0,k*2)x[i]*=y[i];
            NTT(x,1);
            b.insert(b.end(),x.begin()+k,x.end());
        } b.resize(n); return b;
    }
    Poly pow(ll t){
        if(t==0){
            Poly res(this->size()); res[0]=1;
            return res;
        }
        int n=this->size(),k=0; while(k<n and (*this)[k]==0)k++;
        Poly res(n); if(__int128_t(t)*k>=n)return res;
        n-=t*k; Poly g(n); T c=(*this)[k],ic=c.inv();
        rep(i,0,n)g[i]=(*this)[i+k]*ic;
        g=g.log(); for(auto& x:g)x*=t; g=g.exp();
        c=c.pow(t); rep(i,0,n)res[i+t*k]=g[i]*c; return res;
    }
    void NTT(vector<T>& a,bool inv)const;
};

/**
 * @brief Formal Power Series (NTT-friendly mod)
 */
#line 6 "sol.cpp"
using Fp=fp<998244353>;

template <typename Mint> struct NTT {
    static vector<Mint> roots, iroots, rate3, irate3;
    static int max_base;

    NTT() = default;

    static void init() {
        if (roots.empty()) {
        const unsigned mod = Mint::get_mod();
        assert(mod >= 3 && mod % 2 == 1);
        auto tmp = mod - 1;
        max_base = 0;
        while (tmp % 2 == 0)
            tmp >>= 1, max_base++;
        Mint root = 2;
        while (root.pow((mod - 1) >> 1) == 1) {
            root += 1;
        }
        assert(root.pow(mod - 1) == 1);

        roots.resize(max_base + 1);
        iroots.resize(max_base + 1);
        rate3.resize(max_base + 1);
        irate3.resize(max_base + 1);

        roots[max_base] = root.pow((mod - 1) >> max_base);
        iroots[max_base] = Mint(1) / roots[max_base];
        for (int i = max_base - 1; i >= 0; i--) {
            roots[i] = roots[i + 1] * roots[i + 1];
            iroots[i] = iroots[i + 1] * iroots[i + 1];
        }
        {
            Mint prod = 1, iprod = 1;
            for (int i = 0; i <= max_base - 3; i++) {
            rate3[i] = roots[i + 3] * prod;
            irate3[i] = iroots[i + 3] * iprod;
            prod *= iroots[i + 3];
            iprod *= roots[i + 3];
            }
        }
        }
    }

    static void ntt(vector<Mint> &a) {
        init();
        const int n = (int)a.size();
        assert((n & (n - 1)) == 0);
        int h = __builtin_ctz(n);
        assert(h <= max_base);
        int len = 0;
        Mint imag = roots[2];
        if (h & 1) {
        int p = 1 << (h - 1);
        Mint rot = 1;
        for (int i = 0; i < p; i++) {
            auto r = a[i + p];
            a[i + p] = a[i] - r;
            a[i] += r;
        }
        len++;
        }
        for (; len + 1 < h; len += 2) {
        int p = 1 << (h - len - 2);
        { // s = 0
            for (int i = 0; i < p; i++) {
            auto a0 = a[i];
            auto a1 = a[i + p];
            auto a2 = a[i + 2 * p];
            auto a3 = a[i + 3 * p];
            auto a1na3imag = (a1 - a3) * imag;
            auto a0a2 = a0 + a2;
            auto a1a3 = a1 + a3;
            auto a0na2 = a0 - a2;
            a[i] = a0a2 + a1a3;
            a[i + 1 * p] = a0a2 - a1a3;
            a[i + 2 * p] = a0na2 + a1na3imag;
            a[i + 3 * p] = a0na2 - a1na3imag;
            }
        }
        Mint rot = rate3[0];
        for (int s = 1; s < (1 << len); s++) {
            int offset = s << (h - len);
            Mint rot2 = rot * rot;
            Mint rot3 = rot2 * rot;
            for (int i = 0; i < p; i++) {
            auto a0 = a[i + offset];
            auto a1 = a[i + offset + p] * rot;
            auto a2 = a[i + offset + 2 * p] * rot2;
            auto a3 = a[i + offset + 3 * p] * rot3;
            auto a1na3imag = (a1 - a3) * imag;
            auto a0a2 = a0 + a2;
            auto a1a3 = a1 + a3;
            auto a0na2 = a0 - a2;
            a[i + offset] = a0a2 + a1a3;
            a[i + offset + 1 * p] = a0a2 - a1a3;
            a[i + offset + 2 * p] = a0na2 + a1na3imag;
            a[i + offset + 3 * p] = a0na2 - a1na3imag;
            }
            rot *= rate3[__builtin_ctz(~s)];
        }
        }
    }

    static void intt(vector<Mint> &a, bool f = true) {
        init();
        const int n = (int)a.size();
        assert((n & (n - 1)) == 0);
        int h = __builtin_ctz(n);
        assert(h <= max_base);
        int len = h;
        Mint iimag = iroots[2];
        for (; len > 1; len -= 2) {
        int p = 1 << (h - len);
        { // s = 0
            for (int i = 0; i < p; i++) {
            auto a0 = a[i];
            auto a1 = a[i + 1 * p];
            auto a2 = a[i + 2 * p];
            auto a3 = a[i + 3 * p];
            auto a2na3iimag = (a2 - a3) * iimag;
            auto a0na1 = a0 - a1;
            auto a0a1 = a0 + a1;
            auto a2a3 = a2 + a3;
            a[i] = a0a1 + a2a3;
            a[i + 1 * p] = (a0na1 + a2na3iimag);
            a[i + 2 * p] = (a0a1 - a2a3);
            a[i + 3 * p] = (a0na1 - a2na3iimag);
            }
        }
        Mint irot = irate3[0];
        for (int s = 1; s < (1 << (len - 2)); s++) {
            int offset = s << (h - len + 2);
            Mint irot2 = irot * irot;
            Mint irot3 = irot2 * irot;
            for (int i = 0; i < p; i++) {
            auto a0 = a[i + offset];
            auto a1 = a[i + offset + 1 * p];
            auto a2 = a[i + offset + 2 * p];
            auto a3 = a[i + offset + 3 * p];
            auto a2na3iimag = (a2 - a3) * iimag;
            auto a0na1 = a0 - a1;
            auto a0a1 = a0 + a1;
            auto a2a3 = a2 + a3;
            a[i + offset] = a0a1 + a2a3;
            a[i + offset + 1 * p] = (a0na1 + a2na3iimag) * irot;
            a[i + offset + 2 * p] = (a0a1 - a2a3) * irot2;
            a[i + offset + 3 * p] = (a0na1 - a2na3iimag) * irot3;
            }
            irot *= irate3[__builtin_ctz(~s)];
        }
        }
        if (len >= 1) {
        int p = 1 << (h - 1);
        for (int i = 0; i < p; i++) {
            auto ajp = a[i] - a[i + p];
            a[i] += a[i + p];
            a[i + p] = ajp;
        }
        }
        if (f) {
        Mint inv_sz = Mint(1) / n;
        for (int i = 0; i < n; i++)
            a[i] *= inv_sz;
        }
    }

    static vector<Mint> mult(vector<Mint> a, vector<Mint> b) {
        int need = a.size() + b.size() - 1;
        int nbase = 1;
        while ((1 << nbase) < need)
        nbase++;
        int sz = 1 << nbase;
        a.resize(sz, 0);
        b.resize(sz, 0);
        ntt(a);
        ntt(b);
        Mint inv_sz = Mint(1) / sz;
        for (int i = 0; i < sz; i++)
        a[i] *= b[i] * inv_sz;
        intt(a, false);
        a.resize(need);
        return a;
    }
};

template <typename Mint>
vector<Mint>NTT<Mint>::roots = vector<Mint>();
template <typename Mint>
vector<Mint>NTT<Mint>::iroots = vector<Mint>();
template <typename Mint>
vector<Mint>NTT<Mint>::rate3 = vector<Mint>();
template <typename Mint>
vector<Mint>NTT<Mint>::irate3 = vector<Mint>();
template <typename Mint>
int NTT<Mint>::max_base = 0;

NTT<Fp> ntt;
template<>void Poly<Fp>::NTT(vector<Fp>& v,bool inv)const{return inv?ntt.intt(v):ntt.ntt(v);}

template<typename T>Poly<T> comp_ApBx(const Poly<T>& f,T a,T b){ // f(a+bx)
    auto g=f.shift(a.v);
    T pw=1;
    for(auto& x:g){
        x*=pw;
        pw*=b;
    }
    return g;
}

template<typename T>Poly<T> Mobius(const Poly<T>& f,T a,T b,T c,T d){ // f((a+bx)/(c+dx))
    assert(c!=0 or d!=0);
    if(d==0){
        T a_c=a/c,b_c=b/c;
        return comp_ApBx(f,a_c,b_c);
    }
    T p=b/d,q=a-b*c/d;
    auto g=comp_ApBx(f,p,q);
    reverse(ALL(g));
    g=comp_ApBx(g,c,d);
    int n=g.size();
    Poly<T> den(n);
    T cpw=c.pow(n-1),dpw=1,cinv=c.inv();
    rep(i,0,n){
        den[i]=cpw*dpw*nCr<T>(n-1,i);
        cpw*=cinv,dpw*=d;
    }
    g*=den.inv();
    g.resize(n);
    return g;
}

FastIO io;
int main(){
    int n,m;
    io.read(n,m);
    Poly<Fp> a(m);
    rep(i,0,m)io.read(a[i].v);

    a.resize(n*2);
    rep(i,2,SZ(a))a[i]+=a[i-2];
    rep(i,0,SZ(a))a[i]=-a[i];
    a=a.inte().exp();
    auto F0=a<<1;

    F0.resize(n*3+2);
    auto G0=Mobius<Fp>(F0,1,-1,1,1);
    rep(i,0,SZ(G0))G0[i]*=Fp(i*2).pow(n);

    auto Gn=Mobius<Fp>(G0,0,-1,2,1);
    Gn=Gn.shift(-1);

    auto Fn=Gn*a.inv();
    Fn.resize(n+2);
    rep(i,0,n+2)io.write<false,true>(Fn[i].v);
    io.write();
    return 0;
}
0