2019ICPC EC-final C.Dirichlet k -th root(迪利克雷卷积,快速幂)

    科技2022-07-13  126

    题意:

    给定长度为n的g函数值g(1),g(2),…g(n), 已知 g = f ∗ f . . . . . . ∗ f = f k g=f*f......*f=f^k g=ff......f=fk,求f(1),f(2),…f(n)。 式子中的星号表示迪利克雷卷积。 答案对998244353取模。

    数据范围:n<=1e5,k<998244353

    解法:

    g = f k g=f^k g=fk

    g i n v [ k ] = ( f k ) i n v [ k ] g^{inv[k]}=(f^k)^{inv[k]} ginv[k]=(fk)inv[k]

    g i n v [ k ] = f k ∗ i n v [ k ] = f g^{inv[k]}=f^{k*inv[k]}=f ginv[k]=fkinv[k]=f

    直 接 计 算 g i n v [ k ] 即 可 , 用 快 速 幂 算 直接计算g^{inv[k]}即可,用快速幂算 ginv[k]

    迪 利 克 雷 卷 积 O ( n ∗ l o g ) , 快 速 幂 O ( l o g ) , 总 复 杂 度 O ( n ∗ l o g ∗ l o g ) 迪利克雷卷积O(n*log),快速幂O(log),总复杂度O(n*log*log) O(nlog)O(log)O(nloglog)

    code:

    #include<bits/stdc++.h> using namespace std; #define int long long #define ll long long #define PI pair<int,int> const int maxm=1e5+5; const int mod=998244353; int n,k; struct Node{ int a[maxm]; Node operator*(const Node& x)const{ Node ans; memset(ans.a,0,sizeof ans.a); for(int i=1;i<=n;i++){ for(int j=i;j<=n;j+=i){ ans.a[j]=(ans.a[j]+a[i]*x.a[j/i]%mod)%mod; } } return ans; } }; Node a,ans; int ppow(int a,int b,int mod){ int ans=1%mod;a%=mod; while(b){ if(b&1)ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } signed main(){ cin>>n>>k; for(int i=1;i<=n;i++){ cin>>a.a[i]; } ans.a[1]=1; // int b=ppow(k,mod-2,mod); while(b){ if(b&1)ans=ans*a; a=a*a; b>>=1; } for(int i=1;i<=n;i++){ cout<<ans.a[i]<<' '; } return 0; }
    Processed: 0.011, SQL: 8