社区讨论
有没有大佬帮我卡卡常qwq
P5205【模板】多项式开根参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @locju14a
- 此快照首次捕获于
- 2023/10/30 14:58 2 年前
- 此快照最后确认于
- 2023/11/05 02:14 2 年前
直接提交过不去,开了O2才过。是我写的太丑了嘛。有没有大佬帮我看看求逆和开根是不是哪里写炸了?qwq
CPP#include<cstdio>
#define reg register
const int MaxN=800000,g=3,gi=332748118,mod=998244353,inv2=499122177;
inline void read(int &ans)
{
ans=0;
char c=getchar();
while(c<'0'||c>'9')
c=getchar();
while(c>='0'&&c<='9')
ans=ans*10+c-48,c=getchar();
return;
}
int n;
struct poly
{
int val[MaxN+1];
inline int &operator [] (const int &k) {return val[k];}
};
inline void swap(int &a,int &b)
{
const int t=a;
a=b,b=t;
return;
}
inline int add(const int &a,const int &b)
{
const int s=a+b;
return s<mod?s:s-mod;
}
inline int multi(const int &a,const int &b)
{
return 1ll*a*b%mod;
}
inline int pwo(int a,int b)
{
int s=1;
while(b)
{
if(b&1)
s=multi(s,a);
a=multi(a,a),b>>=1;
}
return s;
}
int exgcd(const int &a,const int &b,int &x,int &y)
{
if(!b)
return x=1,y=0,a;
int gcd=exgcd(b,a%b,y,x);
return y-=a/b*x,gcd;
}
inline int inverse(const int &a)
{
int x,y;
return exgcd(a,mod,x,y),add(x,mod);
}
void NTT(poly &a,int lg,int lm,int mode)
{
static int r[MaxN+1];
for(reg int i=1;i<lm;++i)
{
r[i]=(r[i>>1]>>1)|((i&1)<<lg-1);
if(r[i]<i)
swap(a[r[i]],a[i]);
}
for(reg int len=2,mid=1,i,j,k,w,mi,x,y;len<=lm;len<<=1,mid<<=1)
for(i=0,w=pwo(~mode?g:gi,(mod-1)/len);i<lm;i+=len)
for(j=0,mi=1;j<mid;++j,mi=multi(mi,w))
x=a[i+j],y=multi(mi,a[i+mid+j]),a[i+j]=add(x,y),a[i+mid+j]=add(x,mod-y);
if(!~mode)
for(reg int i=0,inv=inverse(lm);i<lm;++i)
a[i]=multi(a[i],inv);
return;
}
void inverse(poly &f,poly &g,int n)
{
static poly f0;
int lm=2,lg=1,len=1;
g[0]=inverse(f[0]);
while(len<=n)
{
++lg,lm<<=1,len<<=1;
for(reg int i=0;i<len;++i)
f0[i]=f[i];
for(reg int i=len;i<lm;++i)
f0[i]=0;
for(reg int i=len>>1;i<lm;++i)
g[i]=0;
NTT(f0,lg,lm,1),NTT(g,lg,lm,1);
for(reg int i=0;i<lm;++i)
g[i]=multi(g[i],add(2,mod-multi(f0[i],g[i])));
NTT(g,lg,lm,-1);
}
for(reg int i=n+1;i<lm;++i)
g[i]=0;
return;
}
void sqrt(poly &f,poly &g,int n)
{
static poly f0,h;
int lm=2,lg=1,len=1;
g[0]=1;
while(len<=n)
{
++lg,lm<<=1,len<<=1;
for(reg int i=0;i<len;++i)
f0[i]=f[i];
inverse(g,h,len);
NTT(f0,lg,lm,1),NTT(h,lg,lm,1);
for(reg int i=0;i<lm;++i)
f0[i]=multi(f0[i],h[i]);
NTT(f0,lg,lm,-1);
for(reg int i=0;i<len;++i)
g[i]=multi(add(g[i],f0[i]),inv2);
}
for(reg int i=n+1;i<len;++i)
g[i]=0;
return;
}
poly f,G;
int main()
{
read(n),n--;
for(reg int i=0;i<=n;++i)
read(f[i]);
sqrt(f,G,n);
for(reg int i=0;i<=n;++i)
printf("%d ",G[i]);
putchar('\n');
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...