[2019 EC-Final] C. Dirichlet kk-th root (狄利克雷卷積的性質+快速冪)
阿新 • • 發佈:2020-12-07
題意:
給定n和k,給定一個數論函式\(g\)的前n項,找到這樣一個數論函式\(f\)使得\(f^k=g\)(在狄利克雷卷積意義下,mod p意義下)(p為質數),列印\(f\)的前n項。(保證\(g(1)=1\))
解法:
在\(g(1)=1\)的條件下可以由\(f^k=g\)推出\(f=g^{1/k}\)(\(1/k是k的逆元\)),然後就可以利用套了快速冪的卷積在\(O(logN*logN*N)\)的時間內求出
程式碼:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll maxn=1e5+5; const ll mod = 998244353; ll fp(ll b,ll p){ ll ans=1; while(p){ if(p&1)ans=ans*b%mod; b=b*b%mod; p>>=1; } return ans; } ll a[maxn],ans[maxn]; ll n,k; ll temp[maxn]; void mul(ll *a,ll *b){//n*logn for(ll i=1;i<=n;i++)temp[i]=0; for(ll i=1;i<=n;i++){ for(ll j=1;i*j<=n;j++){ temp[i*j]=(temp[i*j]+a[i]*b[j])%mod; } } for(ll i=1;i<=n;i++)a[i]=temp[i]; } void solve(){ ans[1]=1; while(k){ if(k&1)mul(ans,a); mul(a,a); k>>=1; } } int main () { scanf("%lld%lld",&n,&k); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); } k=fp(k,mod-2); solve(); for(int i=1;i<=n;i++){ if(i>1)printf(" "); printf("%lld",ans[i]); } }