ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[ABC236H] Distinct Multiples

2022-08-17 21:30:08  阅读:106  来源: 互联网

标签:连通 系数 ABC236H Distinct 容斥 int return include Multiples


一、题目

点此看题

二、解法

考虑容斥第二个限制,如果钦定 \(a_i=a_j\) 我们就连边 \((i,j)\),具体来说我们枚举边集 \(E\) 的子集 \(S\),设 \(f(S)\) 表示满足 \(\forall (u,v)\in S,a_u=a_v\) 的方案数,那么可以写出基础的容斥:

\[\sum_{S} (-1)^{|S|} f(S) \]

设 \(h(n)\) 表示大小为 \(n\) 的连通块,所有可能的连边方案的容斥系数之和,可以得到 \(h(n)=(-1)^{n-1}(n-1)!\);设 \(g(S)=\lfloor \frac{m}{lcm_{i\in S} (a_i)}\rfloor\),用于计算钦定 \(S\) 集合值相同的方案数。

解释一下这个 \(h(n)\) 是怎么得来的,首先有 \(h(1)=1\),考虑如果 \(n\geq 2\) 不要求连通,那么容斥系数和为 \(0\)

考虑用 \(0\) 减去不连通图的容斥系数,设 \(T\subset\{1,2..n\}\) 为 \(1\) 的连通块,如果 \(T\leq n-2\),那么剩下部分的点数 \(\geq 2\),它们的容斥系数是可以奇偶相消的,所以我们只需要计算 \(T=n-1\) 的容斥系数。

考虑枚举这个孤立点,然后我们就得到了子问题,那么有递归式:\(h(n)=-(n-1)h(n-1)\)

所以得到结论:\(h(n)=(-1)^{n-1}(n-1)!\)

考虑 \(dp\) 计算容斥系数,设 \(f(S)\) 表示集合 \(S\) 的容斥系数,每次钦定一个连通块 \(T\) 来转移:

\[f(S)=\sum_{T\subseteq S,T\not=\varnothing,u\in T} h(|T|)\cdot g(T)\cdot f(S-T) \]

那么直接子集枚举,时间复杂度 \(O(3^n)\)

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int MOD = 998244353;
int read()
{
    int x=0,f=1;char c;
    while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    return x*f;
}
int n,m,h[20],g[1<<16],f[1<<16];
int gcd(int a,int b) {return !b?a:gcd(b,a%b);}
int lcm(int a,int b)
{
    if(a>m || b>m) return m+1;
    if(!a || !b) return a+b;
    int g=gcd(a,b);a/=g;
    if((__int128)a*b>m) return m+1;
    return a*b;
}
signed main()
{
    n=read();m=read();
    for(int i=0;i<n;i++)
    {
        int x=read();
        for(int s=0;s<(1<<n);s++) if(s>>i&1)
            g[s]=lcm(g[s],x);
    }
    for(int s=1;s<(1<<n);s++)
        g[s]=(m/g[s])%MOD;
    h[1]=1;
    for(int i=2;i<=n;i++)
        h[i]=(MOD-i+1)*h[i-1]%MOD;
    f[0]=1;
    for(int s=1;s<(1<<n);s++)
    {
        int t=s-(s&(-s));
        for(int i=t;;i=(i-1)&t)
        {
            int j=i^(s&(-s));
            f[s]=(f[s]+f[s-j]*g[j]%MOD
            *h[__builtin_popcountll(j)])%MOD;
            if(i==0) break;
        }
    }
    printf("%lld\n",f[(1<<n)-1]);
}

标签:连通,系数,ABC236H,Distinct,容斥,int,return,include,Multiples
来源: https://www.cnblogs.com/C202044zxy/p/16596812.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有