• 组合数问题


    考场上忘了怎么拆c(a,b)*c(c,a)......

    后来随便想就想出来了...
    先列出答案式子:
    $sum_{i=0}^{n}C_n^if(i)x^i$
    f拆开
    $sum_{i=0}^{n}C_n^ix^isum_{j=0}^{m}a[j]i^j$
    斯特林数拆后面
    $sum_{i=0}^{n}C_n^ix^isum_{j=0}^{m}a[j]sum_{k=j}^{m}s(j,k)frac{i!}{(i-k)!}$
    上下乘k
    $sum_{i=0}^{n}C_n^ix^isum_{j=0}^{m}a[j]sum_{k=j}^{m}k!s(j,k)frac{i!}{(i-k)!k!}$
    变成组合数
    $sum_{i=0}^{n}C_n^ix^isum_{j=0}^{m}a[j]sum_{k=j}^{m}k!s(j,k)C_i^k$
    交换和式
    $sum_{j=0}^{m}a[j]sum_{k=j}^{m}k!s(j,k)sum_{i=0}^{n}C_i^kC_n^ix^i$
    考场上卡在这一步。。。
    有一个公式:
    $C_a^b*C_c^a=C_c^bC_{c-b}^{a-b}$
    用公式化简最后的组合数:
    $sum_{j=0}^{m}a[j]sum_{k=j}^{m}k!s(j,k)sum_{i=0}^{n}C_n^kC_{n-k}^{i-k}x^i$
    再次变换和式
    $sum_{j=0}^{m}a[j]sum_{k=j}^{m}k!s(j,k)C_n^ksum_{i=0}^{n}C_{n-k}^{i-k}x^i$
    调整下界
    $sum_{j=0}^{m}a[j]sum_{k=j}^{m}k!s(j,k)C_n^ksum_{i=k}^{n}C_{n-k}^{i-k}x^i$
    调整后面的和式
    $sum_{j=0}^{m}a[j]sum_{k=j}^{m}k!s(j,k)C_n^kx^ksum_{i=k}^{n}C_{n-k}^{i-k}x^{i-k}$
    二项式展开公式:
    $(x+1)^k=sum_{i=0}^{k}x^kC_k^i$
    后面的和式上下界同时减去k
    $sum_{j=0}^{m}a[j]sum_{k=0}^{j}k!s(j,k)C_n^kx^ksum_{i=0}^{n-k}C_{n-k}^{i}x^{i}$
    二项式展开
    $sum_{j=0}^{m}a[j]sum_{k=0}^{j}k!s(j,k)C_n^kx^k(x+1)^{n-k}$
    问题转变求$C_{n}^{0...m}$m+1个组合数的值
    如果暴力求c时间复杂度很高。
    但是发现相邻两个组合数$C_{n}^{i}$和$C_{n}^{i+1}$的公式只差了两个数。分解质因数后乘积用线段树维护即可。

    up:蒻智了,组合数直接转化为下降幂即可。

    质因数可能较大,要离散化。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1010
    #define int long long
    int pr[N*100],vi[N*100],s[N][N],n,x,mo,m,a[N],pc,ml[N*1000],c[N],p1[N],jc[N],zy[N*2][100],ct[N*2][100],cc[N*2],po[N*100],cg,cv[N*1000],ls[N*100],cq,tt[N*100],cs[N*100],mv[N*100],p2[N];
    int qp(int x,int y){
        int r=1;
        for(;y;y>>=1,x=x*x%mo)
            if(y&1)r=r*x%mo;
        return r;
    }
    void si(){
        for(int i=2;i<N*100;i++){
            if(!vi[i])
                pr[++pc]=i;
            for(int j=1;j<=pc&&i*pr[j]<N*100;j++){
                vi[i*pr[j]]=1;
                if(i%pr[j]==0)break;
            }
        }
    }
    void bd(int o,int l,int r){
        if(l==r){
            ml[o]=1;
            mv[o]=ls[l];
            return;
        }
        int md=(l+r)/2;
        bd(o*2,l,md);
        bd(o*2+1,md+1,r);
        ml[o]=1;
    }
    void mod(int o,int l,int r,int x,int y){
        if(l==r){
            cv[o]=y;
            ml[o]=qp(mv[o],y);
            return;
        }
        int md=(l+r)/2;
        x<=md?mod(o*2,l,md,x,y):mod(o*2+1,md+1,r,x,y);
        ml[o]=ml[o*2]*ml[o*2+1]%mo;
    }
    signed main(){
        si();
        cin>>n>>x>>mo>>m;
        jc[0]=1;
        for(int i=1;i<N;i++)
            jc[i]=jc[i-1]*i%mo;
        for(int i=0;i<N;i++){
            p1[i]=qp(x+1,i);
            p2[i]=qp(x,i);
        }
        for(int i=0;i<=m;i++)
            cin>>a[i];
        c[0]=1;
        for(int i=1;i<=m*2;i++){
            int x=i;
            if(i>m)x=n-i+m+1;
            for(int j=1;pr[j]*pr[j]<=x;j++)
                if(x%pr[j]==0){
                    cc[i]++;
                    zy[i][cc[i]]=pr[j];
                    ls[++cq]=pr[j];
                    while(x%pr[j]==0){
                        ct[i][cc[i]]++;
                        x/=pr[j];
                    }
                }
            if(x!=1){
                cc[i]++;
                zy[i][cc[i]]=x;
                ct[i][cc[i]]=1;
                ls[++cq]=x;
            }
        }
        sort(ls+1,ls+cq+1);
        cq=unique(ls+1,ls+cq+1)-ls-1;
        bd(1,1,cq);
        for(int i=1;i<=m*2;i++)
            for(int j=1;j<=cc[i];j++)
                zy[i][j]=lower_bound(ls+1,ls+cq+1,zy[i][j])-ls;
        for(int i=1;i<=m;i++){
            cg=0;
            for(int j=1;j<=cc[i];j++){
                po[++cg]=zy[i][j];
                cs[zy[i][j]]-=ct[i][j];
            }
            for(int j=1;j<=cc[m+i];j++){
                po[++cg]=zy[m+i][j];
                cs[zy[m+i][j]]+=ct[i+m][j];
            }
            sort(po+1,po+cg+1);
            for(int j=1;j<=cg;j++)
                mod(1,1,cq,po[j],cs[po[j]]);
            c[i]=ml[1];
        }
        for(int i=0;i<N;i++)
            s[i][i]=1;
        for(int i=1;i<N;i++)
            for(int j=1;j<i;j++)
                s[i][j]=(s[i-1][j-1]+s[i-1][j]*j%mo)%mo;
        int v=0;
        for(int j=0;j<=m;j++){
            int r=0;
            for(int k=0;k<=j;k++)
                r=(r+jc[k]%mo*p1[n-k]%mo*p2[k]%mo*c[k]%mo*s[j][k]%mo)%mo;
            v=(v+r*a[j]%mo)%mo;
        }
        cout<<v;
    }
    View Code
  • 相关阅读:
    第45节:Java当中的变量,面向对象
    第45节:Java当中的变量,面向对象
    第44节:Java当中的JVM
    第44节:Java当中的JVM
    第44节:Java当中的JVM
    第43节:Java学前要点
    第43节:Java学前要点
    第43节:Java学前要点
    排名次SQL语句【名次可重复时】
    js5:框架的使用,使框架之间无痕连接
  • 原文地址:https://www.cnblogs.com/cszmc2004/p/13168756.html
Copyright © 2020-2023  润新知