# 【BZOJ3456】城市规划-多项式求逆

$g\left(n\right)=\sum _{i=1}^{n-1}{C}_{n-1}^{i-1}f\left(i\right)g\left(n-i\right)$

$g\left(n\right)=\left(n-1\right)!\sum _{i=1}^{n-1}\frac{f\left(i\right)}{\left(i-1\right)!}\cdot \frac{g\left(n-i\right)}{\left(n-i\right)!}$

$A\left(x\right)=B\left(x\right)C\left(x\right)$
$C$为包含$f\left(i\right)$的那个部分，于是$C\left(x\right)=A\left(x\right){B}^{-1}\left(x\right)$，其中${C}^{-1}\left(x\right)$是多项式$C$的逆。

$C\left(x\right){C}^{-1}\left(x\right)\equiv 1\left(\phantom{\rule{0.667em}{0ex}}\mathrm{mod}\phantom{\rule{thinmathspace}{0ex}}\phantom{\rule{thinmathspace}{0ex}}{x}^{n+1}\right)$

$C\left(x\right)D\left(x\right)\equiv 1\left(\phantom{\rule{0.667em}{0ex}}\mathrm{mod}\phantom{\rule{thinmathspace}{0ex}}\phantom{\rule{thinmathspace}{0ex}}{x}^{n}\right)$

$C\left(x\right){D}^{\prime }\left(x\right)\equiv 1\left(\phantom{\rule{0.667em}{0ex}}\mathrm{mod}\phantom{\rule{thinmathspace}{0ex}}\phantom{\rule{thinmathspace}{0ex}}{x}^{⌈\frac{n}{2}⌉}\right)$

${D}^{\prime }\left(x\right)-D\left(x\right)\equiv 0\left(\phantom{\rule{0.667em}{0ex}}\mathrm{mod}\phantom{\rule{thinmathspace}{0ex}}\phantom{\rule{thinmathspace}{0ex}}{x}^{⌈\frac{n}{2}⌉}\right)$

${D}^{2}\left(x\right)\equiv 2D\left(x\right){D}^{\prime }\left(x\right)-{D}^{\prime 2}\left(x\right)\left(\phantom{\rule{0.667em}{0ex}}\mathrm{mod}\phantom{\rule{thinmathspace}{0ex}}\phantom{\rule{thinmathspace}{0ex}}{x}^{n}\right)$

$D\left(x\right)\equiv 2{D}^{\prime }\left(x\right)-C\left(x\right){D}^{\prime 2}\left(x\right)\left(\phantom{\rule{0.667em}{0ex}}\mathrm{mod}\phantom{\rule{thinmathspace}{0ex}}\phantom{\rule{thinmathspace}{0ex}}{x}^{n}\right)$

$T\left(n\right)=T\left(\frac{n}{2}\right)+O\left(n\mathrm{log}n\right)=O\left(n\mathrm{log}n\right)$

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1004535809;
const ll g=3;
ll n,rev[600010]={0},fac[600010],inv[600010];
ll A[600010]={0},B[600010]={0},C[600010]={0};
ll p[600010]={0},s[600010]={0};

ll power(ll a,ll b)
{
ll s=1,ss=a;
b=(b%(mod-1)+mod-1)%(mod-1);
while(b)
{
if (b&1) s=s*ss%mod;
ss=ss*ss%mod;b>>=1;
}
return s;
}

ll NTT(ll *a,ll type,ll n)
{
for(ll i=0;i<n;i++)
if (i<rev[i]) swap(a[i],a[rev[i]]);
for(ll mid=1;mid<n;mid<<=1)
{
ll W=power(g,type*(mod-1)/(mid<<1));
for(ll l=0;l<n;l+=(mid<<1))
{
ll w=1;
for(ll k=0;k<mid;k++,w=w*W%mod)
{
ll x=a[l+k],y=w*a[l+mid+k]%mod;
a[l+k]=(x+y)%mod;
a[l+mid+k]=(x-y+mod)%mod;
}
}
}
if (type==-1)
{
ll inv=power(n,mod-2);
for(ll i=0;i<=n;i++)
a[i]=a[i]*inv%mod;
}
}

ll calc_rev(ll limit)
{
ll bit=0,x=1;
while(x<=limit) bit++,x<<=1;
rev[0]=0;
for(ll i=1;i<=x;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
return x;
}

void calc_inv(ll *a,ll len)
{
if (len==1)
{
s[0]=power(a[0],mod-2);
return;
}
calc_inv(a,(len+1)>>1);

ll x=calc_rev((len<<1)-1);
memset(p,0,sizeof(p));
for(ll i=0;i<len;i++)
p[i]=a[i];
NTT(s,1,x),NTT(p,1,x);
for(ll i=0;i<=x;i++)
s[i]=(2ll*s[i]-p[i]*s[i]%mod*s[i]%mod+mod)%mod;
NTT(s,-1,x);
for(ll i=len;i<=x;i++)
s[i]=0;
}

int main()
{
scanf("%lld",&n);
fac[0]=fac[1]=1;
for(ll i=1;i<=n;i++)
fac[i]=fac[i-1]*i%mod;
inv[n]=power(fac[n],mod-2);
for(ll i=n;i>=1;i--)
inv[i-1]=inv[i]*i%mod;

for(ll i=0;i<=n;i++)
{
if (i>0) A[i]=power(2ll,i*(i-1)/2ll)*inv[i-1]%mod;
B[i]=power(2ll,i*(i-1)/2ll)*inv[i]%mod;
}
calc_inv(B,n+1);

ll x=calc_rev(n);
NTT(s,1,x),NTT(A,1,x);
for(ll i=0;i<=x;i++)
C[i]=s[i]*A[i]%mod;
NTT(C,-1,x);
printf("%lld",C[n]*fac[n-1]%mod);

return 0;
}
posted @ 2018-06-20 19:17  Maxwei_wzj  阅读(87)  评论(0编辑  收藏  举报