MnZn 求助卡常
查看原帖
MnZn 求助卡常
420129
Nt_Tsumiki楼主2024/9/18 19:07

rt

submission

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <ctime>

#define MOD 998244353
#define N 4000005

using namespace std;
int n,m;

int quickpow(int a,int k) {
    int res=1;
    while (k) {
        if (k&1) res=1ll*res*a%MOD;
        a=1ll*a*a%MOD,k>>=1;
    }
    return res;
} int G=3,iG=quickpow(G,MOD-2);

namespace Poly {
    int to[N];

    void NTT(vector<int> &A,int n,int op) {
        for (int i=0;i<n;i++)
            if (i<to[i]) swap(A[i],A[to[i]]);
        for (int i=1;i<n;i<<=1)
            for (int j=0;j<n;j+=(i<<1)) {
                int w=1,wk=quickpow(op==1?G:iG,(MOD-1)/(i<<1));
                for (int k=0;k<i;k++,w=1ll*w*wk%MOD) {
                    int pe=A[j+k],po=1ll*w*A[i+j+k]%MOD;
                    A[j+k]=(1ll*pe+po)%MOD,A[i+j+k]=(1ll*pe-po+MOD)%MOD;
                }
            }
    }

    void polyde(vector<int> &A,vector<int> &B,int n) {
        for (int i=0;i<n-1;i++)
            B[i]=1ll*(i+1)*A[i+1]%MOD;
        B[n-1]=0;
    }

    void polyinvde(vector<int> &A,vector<int> &B,int n) {
        for (int i=1;i<n;i++)
            B[i]=1ll*A[i-1]*quickpow(i,MOD-2)%MOD;
        B[0]=0;
    }

    void polyinv(vector<int> &A,vector<int> &B,int n) {
        if (n==1)
            return B=vector<int>{quickpow(A[0],MOD-2)},void();
        polyinv(A,B,(n+1)>>1);
        int m=1,K=0;
        while (m<(n<<1)) m<<=1,K++;
        for (int i=0;i<m;i++)
            to[i]=(to[i>>1]>>1)|((i&1)<<(K-1));
        vector<int> C(m,0);
        for (int i=0;i<n;i++) C[i]=A[i];
        B.resize(m);
        NTT(C,m,1); NTT(B,m,1);
        for (int i=0;i<m;i++)
            B[i]=(2ll*B[i]%MOD-1ll*C[i]*B[i]%MOD*B[i]%MOD+MOD)%MOD;
        NTT(B,m,-1);
        int invm=quickpow(m,MOD-2);
        for (int i=0;i<n;i++) B[i]=1ll*B[i]*invm%MOD;
        B.resize(n);
    }

    void polyln(vector<int> &A,vector<int> &B,int n) {
        int m=1,K=0;
        while (m<(n<<1)) m<<=1,K++;
        for (int i=0;i<m;i++)
            to[i]=(to[i>>1]>>1)|((i&1)<<(K-1));
        vector<int> C(m,0),D;
        polyde(A,C,n); polyinv(A,D,n);
        C.resize(m); D.resize(m);
        NTT(C,m,1); NTT(D,m,1);
        for (int i=0;i<m;i++)
            C[i]=1ll*C[i]*D[i]%MOD;
        NTT(C,m,-1);
        int invm=quickpow(m,MOD-2);
        for (int i=0;i<n;i++) C[i]=1ll*C[i]*invm%MOD;
        C.resize(n); B.resize(n);
        polyinvde(C,B,n);
    }

    void polyexp(vector<int> &A,vector<int> &B,int n) {
        if (n==1) return B=vector<int>{1},void();
        polyexp(A,B,(n+1)>>1);
        int m=1,K=0;
        while (m<(n<<1)) m<<=1,K++;
        for (int i=0;i<m;i++)
            to[i]=(to[i>>1]>>1)|((i&1)<<(K-1));
        vector<int> C;
        B.resize(n); polyln(B,C,n);
        B.resize(m); C.resize(m);
        for (int i=0;i<n;i++) C[i]=(A[i]-C[i]+MOD)%MOD;
        (++C[0])%=MOD;
        NTT(B,m,1); NTT(C,m,1);
        for (int i=0;i<m;i++)
            B[i]=1ll*B[i]*C[i]%MOD;
        NTT(B,m,-1);
        int invm=quickpow(m,MOD-2);
        for (int i=0;i<n;i++) B[i]=1ll*B[i]*invm%MOD;
        B.resize(n);  
    }

    void polyquickpow(vector<int> &A,vector<int> &B,int n,int k1,int k2) {
        int m=n; B.resize(n,0);
        for (int i=0;i<n;i++)
            if (A[i]) { m=i; break; }
        if (m==n) return;
        vector<int> C(n-m,0),D;
        int c1=quickpow(A[m],MOD-2),c2=quickpow(A[m],k2);
        for (int i=0;i<n-m;i++) C[i]=1ll*A[i+m]*c1%MOD;
        polyln(C,D,n-m);
        for (int i=0;i<n-m;i++) D[i]=1ll*D[i]*k1%MOD;
        polyexp(D,C,n-m);
        m=min(1ll*m*k1,1ll*n);
        for (int i=0;i<m;i++) B[i]=0;
        for (int i=m;i<n;i++) B[i]=1ll*C[i-m]*c2%MOD;
    }
}
using namespace Poly;
vector<int> f,g;

inline int R() {
    int x=0; char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) x=x*10+c-'0',c=getchar();
    return x;
}

inline void W(int x) {
    if (x>9) W(x/10);
    putchar(x%10+'0');
}

int main() {
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    n=R();
    int k1=0,k2=0,k3=0; string s;
    cin>>s;
    for (auto c:s) {
        k1=(k1*10ll+c-'0')%MOD;
        k2=(k2*10ll+c-'0')%(MOD-1);
    }
    for (int i=0;i<min(6,(int)s.size());i++)
        k3=k3*10ll+s[i]-'0';
    f.resize(n,0);
    for (int i=0;i<n;i++) f[i]=R();
    if (f[0] or k3<n) polyquickpow(f,g,n,k1,k2);
    else g.resize(n);
    for (int i=0;i<n;i++) W(g[i]),putchar(' ');
    putchar('\n');
    // cout<<1.0*clock()/CLOCKS_PER_SEC<<'\n';
    return 0;
}
2024/9/18 19:07
加载中...