zoukankan      html  css  js  c++  java
  • 「HAOI2018」染色 解题报告

    「HAOI2018」染色

    是个套路题..

    考虑容斥

    则恰好为(k)个颜色恰好为(c)次的贡献为

    [inom{m}{k}sum_{ige k}(-1)^{i-k}inom{m-k}{i-k}inom{n}{si}frac{(si)!}{(s!)^i}(m-i)^{n-si} ]

    有两项最开始搞忘了..(inom{n}{si}frac{(si)!}{(s!)^i})就是这两个

    代表钦定(si)个位置去染,然后染色本身是个可重排列

    (d=min(lfloor frac{n}{s} floor,m))

    那么答案就是

    [egin{aligned} ans&=sum_{k=0}^dw_kinom{m}{k}sum_{ige k}(-1)^{i-k}inom{m-k}{i-k}inom{n}{si}frac{(si)!}{(s!)^i}(m-i)^{n-si}\ &=sum_{i=0}^d(-1)^i(m-i)^{n-si}inom{n}{si}frac{(si)!}{(s!)^i}sum_{k=0}^iw_kinom{m}{k}(-1)^kinom{m-k}{i-k}\ &=sum_{i=0}^d(-1)^i(m-i)^{n-si}frac{m!}{(m-i)!}inom{n}{si}frac{(si)!}{(s!)^i}sum_{k=0}^ifrac{w_k(-1)^k}{k!}frac{1}{(i-k)!} end{aligned} ]

    然后随便预处理卷一下就好了


    Code:

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    template <class T>
    void read(T &x)
    {
        x=0;char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
    }
    const int N=(1<<20)+10;
    using std::min;
    using std::max;
    const int mod=1004535809,Gi=334845270;
    inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
    #define mul(a,b) (1ll*(a)*(b)%mod)
    int qp(int d,int k){int f=1;while(k){if(k&1)f=mul(f,d);d=mul(d,d),k>>=1;}return f;}
    int w[N],a[N],b[N],fac[N*10],inv[N*10],turn[N];
    void NTT(int *a,int len,int typ)
    {
        int L=-1;for(int i=1;i<len;i<<=1) ++L;
        for(int i=0;i<len;i++)
        {
            turn[i]=turn[i>>1]>>1|(i&1)<<L;
            if(i<turn[i]) std::swap(a[i],a[turn[i]]);
        }
        for(int le=1;le<len;le<<=1)
        {
            int wn=qp(typ?3:Gi,(mod-1)/(le<<1));
            for(int p=0;p<len;p+=le<<1)
            {
                int w=1;
                for(int i=p;i<p+le;i++,w=mul(w,wn))
                {
                    int x=a[i],y=mul(w,a[i+le]);
                    a[i]=add(x,y);
                    a[i+le]=add(x,mod-y);
                }
            }
        }
        if(!typ)
        {
            int inv=qp(len,mod-2);
            for(int i=0;i<len;i++) a[i]=mul(a[i],inv);
        }
    }
    int main()
    {
        int n,m,s,len=1,u,d;
        read(n),read(m),read(s);
        for(int i=0;i<=m;i++) read(w[i]);
        d=min(n/s,m);
        while(len<=d) len<<=1;
        u=max(n,max(m,len));
        fac[0]=1;for(int i=1;i<=u;i++) fac[i]=mul(fac[i-1],i);
        inv[u]=qp(fac[u],mod-2);
        for(int i=u-1;~i;i--) inv[i]=mul(inv[i+1],i+1);
        int ans=0;
        for(int i=0;i<len;i++)
        {
            a[i]=mul(w[i],inv[i]);
            if(i&1) a[i]=add(mod,-a[i]);
            b[i]=inv[i];
        }
        NTT(a,len<<1,1),NTT(b,len<<1,1);
        for(int i=0;i<len<<1;i++) a[i]=mul(a[i],b[i]);
        NTT(a,len<<1,0);
        for(int i=0;i<=d;i++)
        {
            int sum=(i&1)?mod-1:1;
            sum=mul(sum,mul(qp(m-i,n-s*i),mul(fac[m],mul(inv[m-i],a[i]))));
            sum=mul(sum,mul(fac[n],mul(inv[n-s*i],qp(inv[s],i))));
            ans=add(ans,sum);
        }
        printf("%d
    ",ans);
        return 0;
    }
    

    2019.3.8

  • 相关阅读:
    单片机就那点资源,为啥还要用RTOS?
    JVM 虚拟机参数配置
    C# 多态virtual标记重写 以及EF6 查询性能AsNoTracking
    C# HttpClient发送请求获取接口数据
    C# Socket服务端和客户端通话
    C# 生成图片验证码 图片缩略图 水印
    ADO.NET 帮助类 参数传递 存储过程 分页
    hadoop单机部署
    tengine-sticky
    redis持久化
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10498162.html
Copyright © 2011-2022 走看看