题目大意:
给定两个长为n的数列F和B,求长为n的数列x,使得
在模998244353意义下成立。
题解:
考虑令
,那么
,因此可以再
时间内通过
求出
。
将题目中的F改写成f,有:
记
,那么
,因此知道x(n)后可以
时间内求出
。
根据上文结论,知道
之后可以
时间内求出
,进而求出
,进而求出
具体来说,以已知
求
,代码大致如下:
for(int i=1;i<=n;i++) f[i]=F[i];
for(int i=1;i<=n;i++)
for(int j=i<<1;j<=n;j++)
f[j]-=f[i];
另一个同理。
代码:
// luogu-judger-enable-o2
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 100010
#define mod 998244353
#define lint long long
#define gc getchar()
using namespace std;
int f[N],x[N],fi[N];
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
inline int mol(int x) { return x%=mod,(x<0?x+=mod:x); }
inline int fast_pow(int x,int k=mod-2,int ans=1)
{ for(;k;k>>=1,x=(lint)x*x%mod) (k&1)?ans=(lint)ans*x%mod:0;return ans; }
inline int getf(int *f,int n)
{
for(int i=1;i<=n;i++)
for(int j=i<<1;j<=n;j+=i) f[j]=mol(f[j]-f[i]);
return 0;
}
inline int getg(int *g,int n)
{
for(int i=n;i>=1;i--)
for(int j=i<<1;j<=n;j+=i) g[i]=mol(g[i]-g[j]);
return 0;
}
int main()
{
int n=inn();
for(int i=1;i<=n;i++) f[i]=inn();getf(f,n);
for(int i=1;i<=n;i++) fi[i]=fast_pow(f[i]);
for(int i=1;i<=n;i++) x[i]=inn();getf(x,n);
for(int i=1;i<=n;i++) x[i]=(lint)x[i]*fi[i]%mod;
getg(x,n);for(int i=1;i<=n;i++) printf("%d ",x[i]);
return !printf("\n");
}