zoukankan      html  css  js  c++  java
  • BZOJ 5306 [HAOI2018] 染色

    BZOJ 5306 [HAOI2018] 染色

    首先,求出$N$个位置,出现次数恰好为$S$的颜色至少有$K$种。

    方案数显然为$a_i=frac{n! imes (m-i)^{m-i imes s}}{(m-K)! imes (s!)^K} imes C(m,K)$

    然后二项式反演一下,得到恰好的数量:$ans_i=sumlimits_{j=i}^n (-1)^{j-i} imes a_i imes C(j,i)$

    然后展开一下就可以得到两个多项式:$A_i=frac{m! imes n! imes (m-i)^{m-i imes s}}{(m-i)! imes (n-s imes i)! imes (s!)i},b_i=frac{(-1){m-i}}{(m-i)!}$

    然后显然答案方案数就是:$C=A imes B ,ans_i=frac{C[m+i]}{i!}$

    最后加一下权即可!

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <iostream>
    #include <bitset>
    using namespace std;
    #define N 262205
    #define ll long long
    #define mod 1004535809
    int a[N],b[N],w[N],n,m,s,lim,fac[10000005],inv[10000005],ans;
    int q_pow(int x,int n){int ret=1;for(;n;n>>=1,x=(ll)x*x%mod)if(n&1)ret=(ll)ret*x%mod;return ret;}
    #define inv(x) q_pow(x,mod-2)
    void NTT(int *a,int len,int flag)
    {
        int i,j,k,t,w,x,tmp;
        for(i=k=0;i<len;i++)
        {
            if(i>k)swap(a[i],a[k]);
            for(j=len>>1;(k^=j)<j;j>>=1);
        }
        for(k=2;k<=len;k<<=1)
        {
            t=k>>1;x=q_pow(3,(mod-1)/k);if(flag==-1)x=inv(x);
            for(i=0;i<len;i+=k)
                for(j=i,w=1;j<i+t;j++)
                {
                    tmp=(ll)w*a[j+t]%mod;
                    a[j+t]=(a[j]-tmp+mod)%mod;
                    a[j]=(a[j]+tmp)%mod;w=(ll)w*x%mod;
                }
        }if(flag==-1)for(i=0,t=inv(len);i<len;i++)a[i]=(ll)a[i]*t%mod;
    }
    void init()
    {
        int lim=max(n,m);fac[0]=1;
        for(int i=1;i<=lim;i++)fac[i]=(ll)i*fac[i-1]%mod;inv[lim]=q_pow(fac[lim],mod-2);
        for(int i=lim;i;i--)inv[i-1]=(ll)i*inv[i]%mod;
        lim=min(m,n/s);
        for(int i=0;i<=lim;i++)a[i]=(ll)fac[m]*inv[m-i]%mod*fac[n]%mod*inv[n-s*i]%mod*q_pow(inv[s],i)%mod*q_pow(m-i,n-i*s)%mod;
        for(int i=0;i<=m;i++)
            if((m-i)&1)b[i]=mod-inv[m-i];
            else b[i]=inv[m-i];
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&s);init();
        for(int i=0;i<=m;i++)scanf("%d",&w[i]);
        int len=1;while(len<=(m<<1))len<<=1;
        NTT(a,len,1);NTT(b,len,1);for(int i=0;i<len;i++)a[i]=(ll)a[i]*b[i]%mod;NTT(a,len,-1);
        for(int i=0;i<=m;i++)ans=(ans+(ll)w[i]*a[m+i]%mod*inv[i])%mod;
        printf("%d
    ",ans);
    }
    
  • 相关阅读:
    input清楚阴影 number属性
    转 溢出隐藏
    多行,溢出隐藏 css
    JS判断移动端还是PC端(改造自腾讯网) 仅用于宣传动画,下载页等
    项目开发(Require + E.js)
    showPrompt弹框提示
    图形验证码
    CSS常用技术总结!~~
    移动开发常用技术总结!~~
    JavaScript常用技术总结!~~
  • 原文地址:https://www.cnblogs.com/Winniechen/p/10623368.html
Copyright © 2011-2022 走看看