• 几个多项式的题


    4555: [Tjoi2016&Heoi2016]求和

    第二类斯特林数是把n个物品分到x个无标号盒子的方案数

    那么$s(i,j)*(j!)$就是把n个物品分到x个有标号的盒子的方案数

    $f(n)=sum _{j=1}^{n}s(n,j)*(j!)$

    $f(n)$即把n个物品分到任意个有标号盒子的方案数

    $f(i)=sum_{j=1}^{i}C(i,j)*f(i-j)$ 枚举最后一个盒子装的球的个数

    $f(n)=sum _{j=1}^{n}s(n,j)*(j!)*(2^j)$

    $f(i)=2*sum_{j=1}^{i}C(i,j)*f(i-j)$ 多一个盒子

    $f(i)/i!= sum_{j=1}^{i}2/j!*f(i-j)/(i-j)!$

    $设F(i)=f(i)/i!$

    $f(i)=2/i!$

    $f=f*g+1$

    $(f(0)=1)$

    $f=1/(1-g)$

    多项式求逆即可

     1 //Achen
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<queue>
     9 #include<cmath>
    10 #include<set>
    11 #include<map>
    12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    14 const int N=4e5+7,p=998244353,gg=3,gi=332748118;
    15 typedef long long LL; 
    16 typedef double db;
    17 using namespace std;
    18 int n;
    19 LL f[N],g[N];
    20 
    21 template<typename T> void read(T &x) {
    22     char ch=getchar(); x=0; T f=1;
    23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    24     if(ch=='-') f=-1,ch=getchar();
    25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    26 }
    27 
    28 LL ksm(LL a,LL b) {
    29     LL rs=1,bs=a%p;
    30     while(b) {
    31         if(b&1) rs=rs*bs%p;
    32         bs=bs*bs%p;
    33         b>>=1;
    34     }
    35     return rs;
    36 }
    37 
    38 int r[N];
    39 void FFT(LL a[],int n,int l,int f) {
    40     For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    41     For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
    42     for(int i=1;i<n;i<<=1) {
    43         LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
    44         for(int j=0,pp=(i<<1);j<n;j+=pp) {
    45             LL w=1;
    46             for(int k=0;k<i;k++,w=w*wn%p) {
    47                 LL x=a[j+k],y=w*a[j+k+i]%p;
    48                 a[j+k]=(x+y)%p; a[j+k+i]=(x-y+p)%p;
    49             }
    50         }
    51     }
    52     if(f==-1) {
    53         LL inv=ksm(n,p-2);
    54         For(i,0,n-1) a[i]=a[i]*inv%p;
    55     }
    56 }
    57 
    58 LL tp[N],inv[N],fac[N];
    59 void get_inv(LL a[],LL b[],int n,int l) {
    60     if(n==1) {
    61         b[0]=ksm(a[0],p-2);
    62         return;
    63     }
    64     get_inv(a,b,n>>1,l-1);
    65     For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
    66     FFT(tp,(n<<1),l+1,1);
    67     FFT(b,(n<<1),l+1,1);
    68     For(i,0,(n<<1)) tp[i]=(2LL-tp[i]*b[i]%p+p)%p*b[i]%p;
    69     FFT(tp,(n<<1),l+1,-1);
    70     For(i,0,n-1) b[i]=tp[i],b[i+n]=0;
    71 }
    72 
    73 //#define DEBUG
    74 int main() {
    75 #ifdef DEBUG
    76     freopen("1.in","r",stdin);
    77     //freopen(".out","w",stdout);
    78 #endif
    79     read(n);
    80        inv[0]=inv[1]=1; fac[0]=1;
    81       For(i,2,n) inv[i]=p-p/i*inv[p%i]%p;
    82       For(i,1,n) fac[i]=fac[i-1]*i%p,inv[i]=inv[i-1]*inv[i]%p;
    83     For(i,1,n) g[i]=(p-2LL*inv[i]%p)%p; g[0]=1;
    84       int nn=1,ll=0;
    85       for(;nn<=n+1;nn<<=1) ll++;
    86      get_inv(g,f,nn,ll);
    87      LL ans=0;
    88      For(i,0,nn-1) ans=(ans+f[i]*fac[i])%p;
    89      printf("%lld
    ",ans%p);
    90     return 0;
    91 }
    View Code

    3456: 城市规划

    求n个点的简单(无重边无自环)无向连通图数目.

    $f(n)表示n个点的简单无向图的个数$

    $f(n)=2^{C(n,2)}$

    $g(n)表示n个点的简单无向连通图的个数$

    $f(n)=sum_{i=1}^nC(n-1,i-1)*g(i)*f(n-i)$

    (枚举1所在联通块的大小)

    $f(n)/(n-1)!=sum_{i=1}^ng(i)/(i-1)!*f(n-i)/(n-i)!$

    $设F(n)=f(n)/(n-1)$

    $G(n)=g(n)/(n-1)!$

    $H(n)=f(n)/n!$

    $F=G*H$

    $G=F/H$

    多项式求逆

      1 //Achen
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<vector>
      7 #include<cstdio>
      8 #include<queue>
      9 #include<cmath>
     10 #include<set>
     11 #include<map>
     12 const int N=1621470,p=1004535809,gg=3,gi=334845270;
     13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     15 typedef long long LL; 
     16 typedef double db;
     17 using namespace std;
     18 int n;
     19 LL g[N],h[N],h_inv[N],fac[N],inv[N];
     20 
     21 template<typename T> void read(T &x) {
     22     char ch=getchar(); x=0; T f=1;
     23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     24     if(ch=='-') f=-1,ch=getchar();
     25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     26 }
     27 
     28 LL ksm(LL a,LL b) {
     29     LL rs=1,bs=a%p;
     30     while(b) {
     31         if(b&1) rs=rs*bs%p;
     32         bs=bs*bs%p;
     33         b>>=1;
     34     }
     35     return rs;
     36 }
     37 
     38 
     39 int r[N];
     40 void FFT(LL a[],int n,int l,int f) {
     41     For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
     42     For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
     43     for(int i=1;i<n;i<<=1) {
     44         LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
     45         for(int j=0,pp=(i<<1);j<n;j+=pp) {
     46             LL w=1;
     47             for(int k=0;k<i;k++,w=w*wn%p) {
     48                 LL x=a[j+k],y=w*a[j+k+i]%p;
     49                 a[j+k]=(x+y)%p; a[j+k+i]=(x-y+p)%p;
     50             }
     51         }
     52     }
     53     if(f==-1) {
     54         LL inv=ksm(n,p-2);
     55         For(i,0,n-1) a[i]=a[i]*inv%p;
     56     }
     57 }
     58 
     59 LL tp[N];
     60 void get_inv(LL a[],LL b[],int n,int l) {
     61     if(n==1) {
     62         b[0]=ksm(a[0],p-2);
     63         return;
     64     }
     65     get_inv(a,b,n>>1,l-1);
     66     For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
     67     FFT(tp,(n<<1),l+1,1);
     68     FFT(b,(n<<1),l+1,1);
     69     For(i,0,(n<<1)) tp[i]=(2LL-tp[i]*b[i]%p+p)%p*b[i]%p;
     70     FFT(tp,(n<<1),l+1,-1);
     71     For(i,0,n-1) b[i]=tp[i],b[i+n]=0;
     72 }
     73 
     74 LL C(int n,int m) { if(m<0||n<m) return 0; return fac[n]*inv[m]%p*inv[n-m]%p; }
     75 
     76 //#define DEBUG
     77 int main() {
     78 #ifdef DEBUG
     79     freopen("1.in","r",stdin);
     80     //freopen(".out","w",stdout);
     81 #endif
     82     read(n);
     83     fac[0]=1; inv[0]=inv[1]=1;
     84     For(i,2,n+1) inv[i]=p-p/i*inv[p%i]%p;
     85     For(i,1,n+1) fac[i]=fac[i-1]*i%p,inv[i]=inv[i-1]*inv[i]%p;
     86     For(i,0,n) {
     87         LL tp=ksm(2,((LL)i*(i-1)/2)%(p-1));
     88         if(i) g[i]=tp*inv[i-1]%p;
     89         h[i]=tp*inv[i]%p;
     90     }
     91     //For(i,0,n) printf("%lld ",g[i]); puts("");
     92     //For(i,0,n) printf("%lld ",h[i]); puts("");
     93     int nn=1,ll=0;
     94     for(;nn<=2*(n+1);nn<<=1) ll++;
     95     get_inv(h,h_inv,nn>>1,ll-1);
     96     //For(i,0,n) printf("%lld ",h_inv[i]); puts("");
     97     FFT(h_inv,nn,ll,1); FFT(g,nn,ll,1);
     98     For(i,0,nn) g[i]=g[i]*h_inv[i]%p;
     99     FFT(g,nn,ll,-1);
    100     //For(i,0,100) printf("%lld ",g[i]); puts("");
    101     printf("%lld
    ",g[n]*fac[n-1]%p);
    102     return 0;
    103 }
    View Code

    3625: [Codeforces Round #250]小朋友和二叉树

    $设c的生成函数为g$

    $神犇二叉树的个数的生成函数为f$

    $有f=f*f*g+1$ (空节点)

    $f=(1+sqrt(1-4*g))/2*g$

    $或f=(1-sqrt(1-4*g))/2*g$

    $g(0)=0(c>1),所以上面1的常数项一定是取减号后抵消了$

    $f=(1+sqrt(1-4*g))/2*g$

    多项式开根。
    牛顿迭代。

    因为常数不优秀,cf上可以过,bz上会t

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #include<set>
    #include<map>
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    const int N=4e5+7,p=998244353,gg=3,gi=332748118;
    typedef long long LL; 
    typedef double db;
    using namespace std;
    int n,m;
    LL h[N],g[N],inv_2;
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    LL ksm(LL a,LL b) {
        LL rs=1,bs=a%p;
        while(b) {
            if(b&1) rs=rs*bs%p;
            bs=bs*bs%p;
            b>>=1;
        }
        return rs;
    }
    
    void FFT(LL a[],int n,int l,int f) {
        static int r[N];
        For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<l-1);
        For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
        for(int i=1;i<n;i<<=1) {
            LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
            for(int j=0,pp=(i<<1);j<n;j+=pp) {
                LL w=1;
                for(int k=0;k<i;k++,w=w*wn%p) {
                    LL x=a[j+k]%p,y=a[j+k+i]*w%p;
                    a[j+k]=(x+y)%p,a[j+k+i]=(x-y+p)%p;
                }
            }
        }
        if(f==-1) {
            LL invv=ksm(n,p-2);
            For(i,0,n-1) a[i]=a[i]*invv%p;
        }
    }
    
    LL tp[N],h_inv[N];
    void get_inv(LL a[],LL b[],int n,int l) {
        if(n==1) {
            b[0]=ksm(a[0],p-2); 
            return ;
        }
        get_inv(a,b,n>>1,l-1);
        For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
        FFT(tp,n<<1,l+1,1);
        FFT(b,n<<1,l+1,1);
        For(i,0,n<<1) tp[i]=(2LL-tp[i]*b[i]%p+p)%p*b[i]%p;
        FFT(tp,n<<1,l+1,-1);
        For(i,0,n-1) b[i]=tp[i],b[i+n]=0; 
    }
    
    LL h_sqr[N],a_t[N],b_t[N];
    void get_sqr(LL a[],LL b[],int n,int l) {
        if(n==1) {
            b[0]=sqrt(a[0]);
            return;
        }
        get_sqr(a,b,n>>1,l-1);
        For(i,0,n<<1) b_t[i]=0;
        For(i,0,n-1) a_t[i]=a[i],a_t[i+n]=0;
        get_inv(b,b_t,n,l);
        FFT(b,n<<1,l+1,1);
        FFT(a_t,n<<1,l+1,1);
        FFT(b_t,n<<1,l+1,1);
        For(i,0,n<<1) b[i]=(b[i]+a_t[i]*b_t[i]%p)%p*inv_2%p;
        FFT(b,n<<1,l+1,-1);
        For(i,0,n-1) b[n+i]=0;
    }
    
    //#define DEBUG
    int main() {
    #ifdef DEBUG
        freopen("1.in","r",stdin);
        //freopen(".out","w",stdout);
    #endif
        read(n); read(m);
        inv_2=ksm(2,p-2);
        For(i,1,n) {
            int x; read(x); g[x]++;
        }
        h[0]=1;
        For(i,1,m) if(g[i]) h[i]=(p-4LL*g[i]%p)%p;
        int nn=1,ll=0;
        for(;nn<=m+1;nn<<=1) ll++;
        get_sqr(h,h_sqr,nn,ll);
        h_sqr[0]=(h_sqr[0]+1)%p;
        get_inv(h_sqr,h_inv,nn,ll);
        For(i,1,m) printf("%I64d
    ",(h_inv[i]+h_inv[i])%p);
        return 0;
    }
    View Code

    我真是蠢到不行,遇见式子不要感觉有一点不对劲就盯着它发呆,你好歹去把它化一化啊,多半化一化就出来了,脑子是木的吗我。

    4.27

    3684: 大朋友和多叉树

    第一次写多项式的题写完--虽然写了很久--就过了样例然后1a了,感觉生活又充满了希望

    拉格朗日反演:

    若$G(f(x))=x$

    $[x^n]f(x)=frac{1}{n}[x^{n-1}](frac{x}{G(x)})^n$

    证明是什么,不好吃吧

    $f为答案的生成函数$

    $f(x)=sum_{k in d}f^k(x)+x$

    $f(0)=0$

    $f(x)-sum_{k in d}f^k(x)=x$

    $G(f(x))=f(x)-sum_{k in d}f^k(x)$

    $G(x)=x-sum_{k in d}x^k$

    套用反演公式即可

    $f(x)^k=e^{k*lnf(x)}$

      1 //Achen
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<vector>
      7 #include<cstdio>
      8 #include<queue>
      9 #include<cmath>
     10 #include<set>
     11 #include<map>
     12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     14 const int N=3e5+7,p=950009857,gg=7,gi=135715694;
     15 typedef long long LL; 
     16 typedef double db;
     17 using namespace std;
     18 int n,m;
     19 LL g[N];
     20 
     21 template<typename T> void read(T &x) {
     22     char ch=getchar(); x=0; T f=1;
     23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     24     if(ch=='-') f=-1,ch=getchar();
     25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     26 }
     27 
     28 LL ksm(LL a,LL b) {
     29     LL rs=1,bs=a%p;
     30     while(b) {
     31         if(b&1) rs=rs*bs%p;
     32         bs=bs*bs%p;
     33         b>>=1;
     34     }
     35     return rs;
     36 }
     37 
     38 LL mo(LL x) { return x>=p?x-p:x; }
     39 
     40 void FFT(LL a[],int n,int l,int f) {
     41     static int r[N];
     42     For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<l-1);
     43     For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
     44     for(int i=1;i<n;i<<=1) {
     45         LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
     46         for(int j=0,pp=(i<<1);j<n;j+=pp) {
     47             LL w=1;
     48             for(int k=0;k<i;k++,w=w*wn%p) {
     49                 LL x=a[j+k],y=w*a[j+k+i]%p;
     50                 a[j+k]=mo(x+y); a[j+k+i]=(x-y+p)%p;
     51             }
     52         }
     53     }
     54     if(f==-1) {
     55         LL invv=ksm(n,p-2);
     56         For(i,0,n-1) a[i]=a[i]*invv%p;
     57     }
     58 }
     59 
     60 LL g_inv[N],tp[N];
     61 void get_inv(LL a[],LL b[],int n,int l) {
     62     if(n==1) {
     63         b[0]=ksm(a[0],p-2); 
     64         return;
     65     }
     66     get_inv(a,b,n>>1,l-1);
     67     For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
     68     FFT(tp,n<<1,l+1,1);
     69     FFT(b,n<<1,l+1,1);
     70     For(i,0,n<<1) tp[i]=(2LL-b[i]*tp[i]%p+p)%p*b[i]%p;
     71     FFT(tp,n<<1,l+1,-1);
     72     For(i,0,n-1) b[i]=tp[i],b[i+n]=0;
     73 }
     74 
     75 LL g_ln[N],inv[N];
     76 void get_ln(LL a[],LL b[],int n,int l) {
     77     static LL a_dao[N],a_inv[N];
     78     For(i,0,n<<1) a_dao[i]=a_inv[i]=0;
     79     For(i,1,n-1) a_dao[i-1]=a[i]*i%p; a_dao[n-1]=0;
     80     get_inv(a,a_inv,n,l);
     81     FFT(a_dao,n<<1,l+1,1);
     82     FFT(a_inv,n<<1,l+1,1);
     83     For(i,0,n<<1) a_dao[i]=a_dao[i]*a_inv[i]%p;
     84     FFT(a_dao,n<<1,l+1,-1);
     85     For(i,0,n-1) b[i]=a_dao[i],b[i+n]=0;
     86     Rep(i,n-1,0) b[i]=b[i-1]*inv[i]%p; b[0]=0;
     87 }
     88 
     89 void get_exp(LL a[],LL b[],int n,int l) {
     90     if(n==1) {
     91         b[0]=1; return;
     92     }
     93     get_exp(a,b,n>>1,l-1);
     94     static LL b_ln[N];
     95     For(i,0,n<<1) b_ln[i]=0;
     96     get_ln(b,b_ln,n,l);
     97     For(i,0,n-1) b_ln[i]=((LL)(i==0)-b_ln[i]+a[i]+p)%p;
     98     FFT(b,n<<1,l+1,1);
     99     FFT(b_ln,n<<1,l+1,1);
    100     For(i,0,n<<1) b_ln[i]=b_ln[i]*b[i]%p;
    101     FFT(b_ln,n<<1,l+1,-1);
    102     For(i,0,n-1) b[i]=b_ln[i],b[i+n]=0;
    103 }
    104 
    105 LL g_k[N];
    106 void get_power(LL a[],LL b[],int n,int l,LL k) {
    107     static LL t[N];
    108     For(i,0,n<<1) t[i]=0;
    109     get_ln(a,t,n,l);
    110     For(i,0,n-1) t[i]=t[i]*k%p;
    111     get_exp(t,b,n,l);
    112 }
    113 
    114 //#define DEBUG
    115 int main() {
    116 #ifdef DEBUG
    117     freopen("1.in","r",stdin);
    118     //freopen(".out","w",stdout);
    119 #endif
    120     read(n); read(m);
    121     g[0]=1;
    122     For(i,1,m) { int x; read(x); g[x-1]=mo(g[x-1]+p-1); }
    123     int nn=1,ll=0;
    124     for(nn=1;nn<=n;nn<<=1) ll++;
    125     inv[0]=inv[1]=1;
    126     For(i,2,nn) inv[i]=(p-p/i*inv[p%i]%p)%p;
    127     get_inv(g,g_inv,nn,ll);
    128     get_power(g_inv,g_k,nn,ll,n);
    129     printf("%lld
    ",g_k[n-1]*inv[n]%p);
    130     return 0;
    131 }
    View Code

    最近感觉很不对劲

    不应该是这样的

    不应该是现在这个样子

    各方面都是

    为什么是这样啊

    是哪里不对劲吧

    到底是哪个地方出了问题呀

    可能这周心都已经不在机房了

    或者说省选以来都是这样

    不管怎么说

    终于要回家了

    回家之后或许会有什么变化吧

    不能这样下去

    bad end的flag已经高高立起了

    一定要改变一点什么才行呀

  • 相关阅读:
    LeetCode 120:三角形最小路径和
    守护进程
    G711时间戳增量和数据包大小的关系
    H264防止竞争机制
    硬编码帧率错误导致的浏览器不能播放的问题
    GCC inline
    单例模式的双检锁的隐患和优化
    Java中异常捕获子类异常捕获在父类异常前面,即小范围先被捕获
    线程运行流程图
    将二维数组转为稀疏数组
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8955179.html
Copyright © 2020-2023  润新知