[Study notes] binomial inversion

I guess the question on the exam is a binomial inversion Unfortunately, I will not ah

NTT to divide and conquer the violence in their 60's, however NTT partition can run 1e6 / dk

Return to the topic

Binomial inversion is probably about binomial inversion of (nonsense)

Generally the initial state is the state pressure and shape 0/1 They have good properties which a particular state can be recorded directly irrespective of the number 1

And because the inversion ≈ inclusion and exclusion so it's a good read on two basic forms

$f(n) = \sum_0 ^ n  (-1)^i \binom{n}{i} g(i) \Leftrightarrow g(n) = \sum_0 ^n (-1)^i \binom{n}{i} f(n)$

The persimmon is generally less than (rarely up because it is a form of inclusion-exclusion

$f(n) = \sum _{i=0} ^n \binom{n}{i} g(i) \Leftrightarrow\sum_{i=0}^n (-1)^{n-i} \binom{n}{i} f(i)$

The persimmon is generally more useful qwq

Concrete evidence of their own Baidu it (in fact, I'm lazy ~ ~ ~ ~

 

example

[HAOI2016] staining

In fact, this problem can not be directly binomial inversion inclusion and exclusion also indirect proof of the nature of inversion is the inclusion-exclusion

Consider exactly with k S limit in accordance with a routine into at least k is S

Provided ask function G (x) is a function of the inclusion-exclusion F (x)

Receiving repellent function can be calculated directly $ F (x) = \ binom {m} {x} (mi) ^ {n-ix} \ frac {(sx)!} {(X!) ^ S (n-ix)! } $

Then put directly on top of inclusion and exclusion on it

Finally, you can optimize the NTT

The previous code (persimmons launch last anyway is the same)

//Love and Freedom.
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define ll long long
#define inf 20021225
#define mdn 1004535809
#define N 300010
#define G 3
using namespace std;

int rev[N<<2],inv,jc[N*100],iv[N*100],n,m,s,w[N];
int ksm(int bs,int mi)
{
    int ans=1;
    while(mi)
    {
        if(mi&1)    ans=(ll)ans*bs%mdn;
        bs=(ll)bs*bs%mdn; mi>>=1;
    }
    return years;
}
int pre(int n)
{
    int lim=1,l=0;
    while(lim<n)    lim<<=1,l++;
    for(int i=1;i<lim;i++)
        rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
    inv=ksm(lim,mdn-2); return lim;
}
void ntt(int *a,int lim,int opt)
{
    for(int i=1;i<lim;i++)    if(i<rev[i])
        swap(a[i],a[rev[i]]);
    for(int k=2,mid=1;k<=lim;k<<=1,mid<<=1)
    {
        int Wn=ksm(G,(mdn-1)/k);    if(opt)    Wn=ksm(Wn,mdn-2);
        for(int w=1,i=0;i<lim;w=1,i+=k)    for(int j=0;j<mid;j++,w=(ll)w*Wn%mdn)
        {
            int x=a[i+j],y=(ll)w*a[i+mid+j]%mdn;
            a[i+j]=(x+y)%mdn; a[i+mid+j]=(x-y+mdn)%mdn;
        }
    }
    if(opt)    for(int i=0;i<lim;i++)    a[i]=(ll)a[i]*inv%mdn;
}
int h [N] f [N] years [N]; int top;
int main ()
{
    scanf("%d%d%d",&n,&m,&s);
    for(int i=0;i<=m;i++)    scanf("%d",&w[i]);
    top=min(n/s,m); jc[0]=iv[0]=1; int tt=max(n,m);
    for(int i=1;i<=tt;i++)    jc[i]=(ll)jc[i-1]*i%mdn;
    iv[tt]=ksm(jc[tt],mdn-2); int qwq=1;
    for(int i=tt;i;i--)    iv[i-1]=(ll)iv[i]*i%mdn;
    for(int i=0;i<=top;i++)
        f[i]=(ll)jc[m]*iv[m-i]%mdn*jc[n]%mdn*iv[n-i*s]%mdn*qwq%mdn*ksm(m-i,n-i*s)%mdn,qwq=(ll)qwq*iv[s]%mdn;
    for(int i=0;i<=top;i++)    h[i]=(ll)(mdn+((i&1)?-1:1)*iv[i])%mdn;
    for(int i=0;i<=(top>>1);i++)    swap(h[i],h[top-i]);
    int lim=pre((top+1)<<1);// printf("%d\n",lim);
    ntt(h,lim,0); ntt(f,lim,0);
    for(int i=0;i<lim;i++)    ans[i]=(ll)h[i]*f[i]%mdn;
    ntt(ans,lim,1); int fin=0;
    for(int i=0;i<=top;i++)
        fin=(ll)(fin+(ll)ans[top+i]*w[i]%mdn*iv[i]%mdn)%mdn;
    printf("%d\n",fin);
    return 0;
}
View Code

 

 

[CTS2019] Pearl

On the night before the exam just to see the chances of the original title but did not understand

Consider how much color is odd

Direct to do so is clearly

$G(i) = (\frac{e^x + e^{-x}}{2})^i (\frac{e^x - e^{-x}}{2})^{n-i}$

But also requires n!

Found n1e9 / px

So is the inversion of the binomial

$F(i) = n![x^n](\frac{e^x + e^{-x}}{2})^i e^{(D-i)x}$

We further open parenthesis painting persimmon

$F(i)= \frac{1}{2^i} \sum_{j=0}^i \binom{i}{j} n![x^n]e^{jx-(i-j)x} e^{(D-i)x}$

$F(i)=\frac{1}{2^i}\sum_{j=0}^i \binom{i}{j} n![x^n]e^{(D-2i+2j)x}$

$F(i)=\frac{1}{2^i}\sum_{j=0}^i \binom{i}{j} (D-2i+2j)^n$

A typical form of convolution NTT optimized out on it

Inversion directly into the persimmon continue NTT just fine

(Tucao a human tumor topic open to the n [0,1e18] So also judged Patent 0 / px)

Ah this problem too lazy to go back and write the code to strengthen the direct examination of it lost x

//Love and Freedom.
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#define inf 20021225
#define ll long long
#define N 600010
#define mdn 998244353
#define G 3
using namespace std;
ll read()
{
    ll f=1,s=0; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
int fac[N],inv[N];
void upd(int &x,int y){x+=x+y>=mdn?y-mdn:y;}
int C(int n,int m){return n<m?0:1ll*fac[n]*inv[m]%mdn*inv[n-m]%mdn;}
int ksm(int bs,ll mi)
{
    int ans=1;
    if(!bs)    return !mi?1:0; mi%=(mdn-1);
    while(mi)
    {
        if(mi&1)    ans=1ll*ans*bs%mdn;
        bs=1ll*bs*bs%mdn; mi>>=1;
    }
    return years;
}
int n,m; ll q,k;
int r[N];
int init(int n)
{
    int l=0,lim=1;
    while(lim<n)    lim<<=1,l++;
    for(int i=0;i<lim;i++)
        r[i]=(r[i>>1]>>1)|((i&1)<<l-1);
    return lim;
}
void NTT ( you * a, you're learning, you f)
{
    for(int i=0;i<lim;i++)    if(r[i]>i)
        swap(a[r[i]],a[i]);
    for(int k=2,mid=1;k<=lim;k<<=1,mid<<=1)
    {
        int Wn=ksm(G,(mdn-1)/k); if(f)    Wn=ksm(Wn,mdn-2);
        for(int w=1,i=0;i<lim;i+=k,w=1)    for(int j=0;j<mid;j++,w=1ll*w*Wn%mdn)
        {
            int x=a[i+j],y=1ll*w*a[i+mid+j]%mdn;
            a[i+j]=(x+y)%mdn; a[i+mid+j]=(mdn+x-y)%mdn;
        }
    }
    if(f)    for(int kinv=ksm(lim,mdn-2),i=0;i<lim;i++)
        a[i]=1ll*a[i]*kinv%mdn;
}
int tmp[N],g[N],f[N];
void solve(int *a,int n)
{
    memset(g,0,sizeof(g)); memset(f,0,sizeof(f)); 
    for(int i=0;i<=n;i++)    g[i]=inv[i],f[i]=1ll*(i&1?mdn-inv[i]:inv[i])*ksm((n-2*i+mdn)%mdn,q)%mdn;
    int lim=init(n+1<<1); ntt(g,lim,0); ntt(f,lim,0);
    for(int i=0;i<lim;i++)    g[i]=1ll*g[i]*f[i]%mdn;
    ntt(g,lim,1);
    for(int i=0;i<=n;i++)    g[i]=1ll*ksm(2,(mdn-1-i)%mdn)*fac[i]%mdn*g[i]%mdn;
    for(int i=0;i<=n;i++)    g[i]=1ll*g[i]*fac[i]%mdn*C(n,i)%mdn,f[i]=i&1?mdn-inv[i]:inv[i];
    for(int i=n+1;i<lim;i++)    f[i]=g[i]=0; reverse(f,f+n+1);
    ntt(g,lim,0); ntt(f,lim,0);
    for(int i=0;i<lim;i++)    a[i]=1ll*g[i]*f[i]%mdn;
    ntt(a,lim,1);
    for(int i=0;i<=n;i++)    a[i]=1ll*a[i+n]*inv[i]%mdn;
}
int pre[N],h[N],l[N];
int qry(int l,int r){return l>r?0:l?(pre[r]-pre[l-1]+mdn)%mdn:pre[r];}
int main()
{
    //freopen("qwq.txt","w",stdout);
    n=read(),m=read(),q=read(),k=read(); //printf("%lld %lld\n",q,k);
    int top=max(n,m);
    fac[0]=1; for(int i=1;i<=top;i++)    fac[i]=1ll*fac[i-1]*i%mdn;
    inv[top]=ksm(fac[top],mdn-2); for(int i=top;i;i--)    inv[i-1]=1ll*inv[i]*i%mdn;
    Loose (h, n); Loose (L, M); int ans = 0 ;
    pre[0]=l[0]; for(int i=1;i<=m;i++)    pre[i]=pre[i-1],upd(pre[i],l[i]);
    for(int i=0;i<=n;i++)
    {
        int fm=n-2*i; ll fz=k-1ll*m*i;
        if(!fm)
        {
            if(1ll*m*i<=k)    upd(ans,1ll*h[i]*qry(0,m)%mdn);
        }
        else if(fm<0)
        {
            ll top=ceil((long double)fz/fm); top=max(top,0ll);
            if(top<=m)    upd(ans,1ll*h[i]*qry(top,m)%mdn);
        }
        else
        {
            ll top=floor((long double)fz/fm); top=min(top,(ll)m);
            if(top>=0)    upd(ans,1ll*h[i]*qry(0,top)%mdn);
        }
    }
    printf("%d\n",ans);
    return 0;
}
View Code

 

[CTS2019] Random cube

8 will first dove with (not goo goo not write today x)

Guess you like

Origin www.cnblogs.com/hanyuweining/p/11950267.html