namespace polynomial
{
const ll N=1e7+50,G=3,mod=998244353;
ll r[N],tmp[N];
inline ll ksmod(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans%mod;
}
inline void ntt(ll *a,ll limit,ll pd)
{
fr(i,0,limit-1) if(i<r[i]) swap(a[i],a[r[i]]);
for(ll i=1;i<limit;i<<=1)
{
ll gn=ksmod(G,(mod-1)/(i<<1));
for(ll j=0;j<limit;j+=(i<<1))
{
ll g=1;
for(ll k=0;k<i;++k,g=(g*gn)%mod)
{
ll x=a[j+k],y=g*a[j+k+i]%mod;
a[j+k]=(x+y)%mod,a[j+k+i]=(x-y+mod)%mod;
}
}
}
if(pd==1) return ;
ll inv=ksmod(limit,mod-2);
reverse(a+1,a+limit);
fr(i,0,limit-1) a[i]=a[i]*inv%mod;
}
inline void polyinv(ll n,ll *a,ll *b)
{
if(n==1)
{
b[0]=ksmod(a[0],mod-2);
return ;
}
polyinv((n+1)>>1,a,b);
static ll l=0,limit=1;
while(limit<(n<<1)) limit<<=1,++l;
fr(i,1,limit-1) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
fr(i,0,n-1) tmp[i]=a[i];
fr(i,n,limit-1) tmp[i]=0;
ntt(b,limit,1),ntt(tmp,limit,1);
fr(i,0,limit-1) b[i]=(2*b[i]%mod-(b[i]*b[i]%mod*tmp[i])%mod+mod)%mod;
ntt(b,limit,-1);
fr(i,n,limit-1) b[i]=0;
}
inline void polyderi(ll n,ll *a)
{
fr(i,1,n) a[i-1]=(a[i]*i)%mod;
a[n]=0;
}
inline void polyinte(ll n,ll *a)
{
pfr(i,n,1) a[i]=(a[i-1]*ksmod(i,mod-2))%mod;
a[0]=0;
}
ll b[N],ans[N];
inline void polyln(ll n,ll *a)
{
memcpy(b,a,sizeof(b));
polyderi(n,a),polyinv(n,b,ans);
ll limit=1,l=0;
while(limit<=(n<<1)) limit<<=1,++l;
fr(i,0,limit-1) b[i]=ans[i];
fr(i,1,limit-1) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
ntt(a,limit,1),ntt(b,limit,1);
fr(i,0,limit) a[i]=(a[i]*b[i])%mod;
ntt(a,limit,-1);
polyinte(n,a);
fr(i,n+1,limit) a[i]=0;
}
}
using namespace polynomial;
多项式板子(待完善)
猜你喜欢
转载自www.cnblogs.com/lgj-lgj/p/13392147.html
今日推荐
周排行