题目

给定\(n,c,d\)和序列\(\{b_i\}\),求一个序列\(\{x_i\}\)满足

\[\sum_{j=1}^n\gcd(i,j)^c\times \rm{lcm(i,j)^d}\times x_j\equiv b_i(mod\ P )
\]

不难将\(\rm lcm(i,j)\)写成\(\frac{i\times j}{\gcd(i,j)}\)

\[\sum_{j=1}^n\gcd(i,j)^{c-d}j^dx_j\equiv b_i\times i^{-d}(mod\ P)
\]

套路枚举\(\gcd\),之后套路反演一下,设\(\omega =c-d\)

\[\sum_{d|i}d^{\omega}\sum_{d|k}[k|i]\mu(\frac{k}{d})F(k)\equiv b_i\times i^{-d}(mod\ P)
\]

其中\(F(k)=\sum_{k|t}x_tt^d\)

套路地进行简单和式变换

\[\sum_{k|i}F(k)\sum_{d|k}\mu(\frac{k}{d})d^{\omega}\equiv b_i\times i^{-d}(mod\ P)
\]

设\(g(n)=\sum_{d|n}\mu(\frac{n}{d})d^{\omega}\)

上式即为

\[\sum_{k|i}F(k)g(k)\equiv b_i\times i^{-d}(mod\ P)
\]

不难发现就是一个函数叫做\(F(k)g(k)\)卷上了一个\(1\)得到了右边那个函数,不妨称之为\(B(i)\)

则\(F(i)g(i)=(\mu\times B)(i)\)

于是\(F(i)=\frac{(\mu\times B)(i)}{g(i)}\),得到\(F\)之后再和\(\mu\)卷一波就能求\(x\)了

卷\(\mu\)完全可以用高维差分优化到\(O(n\log \log n)\),所以要是写个线筛\(i^k\)和离线求逆元就是\(O(qn\log \log n)\)复杂度了

显然我懒得写

代码

#include<bits/stdc++.h>
#define re register
const int maxn=1e5+5;
const int mod=998244353;
inline int dqm(int x){return x<0?x+mod:x;}
inline int qm(int x) {return x>=mod?x-mod:x;}
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int f[maxn],p[maxn>>1],b[maxn],g[maxn],n,c,d;
inline int ksm(int a,int b) {
b%=(mod-1);if(b<0) b+=mod-1;
int S=1;for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) S=1ll*S*a%mod;return S;
}
inline void work() {
for(re int i=1;i<=n;i++) b[i]=1ll*read()*ksm(i,-d)%mod;
for(re int i=1;i<=p[0];++i)
for(re int j=n/p[i];j;--j) b[j*p[i]]=dqm(b[j*p[i]]-b[j]);
for(re int i=1;i<=n;i++)
if(g[i]==0&&b[i]) {puts("-1");return;}else b[i]=1ll*b[i]*g[i]%mod;
for(re int i=1;i<=p[0];++i)
for(re int T=n/p[i],j=1;j<=T;++j) b[j]=dqm(b[j]-b[p[i]*j]);
for(re int i=1;i<=n;i++) printf("%d ",1ll*b[i]*ksm(i,-d)%mod);
puts("");
}
int main() {
n=read(),c=read(),d=read();c%=(mod-1),d%=(mod-1);
for(re int i=2;i<=n;i++) {
if(!f[i]) p[++p[0]]=i;
for(re int j=1;j<=p[0]&&p[j]*i<=n;++j) {
f[p[j]*i]=1;if(i%p[j]==0)break;
}
}
for(re int i=1;i<=n;i++) g[i]=ksm(i,c-d);
for(re int i=p[0];i;--i)
for(re int j=n/p[i];j;--j) g[p[i]*j]=dqm(g[p[i]*j]-g[j]);
for(re int i=1;i<=n;i++) g[i]=ksm(g[i],mod-2);
for(re int Q=read();Q;--Q) work();return 0;
}
05-19 04:02