• hihoCoder #1867 GCD


    在集合 $[n]$ 上使用容斥原理。

    固定 $i$,考虑有多少个 $j in [n]$ 满足 $gcd(i, j) = gcd(a_i, a_j) = 1$,将此数目记作 $f_i$。暂时不考虑条件 $ i le j $ 。

    考虑 $[n]$ 的某些子集。$S_{x,y} := { iin [n] colon xmid i, y mid a_i }$

    以 $a_6 = 4$ 为例,$6$ 的素因子有 $2, 3$,$4$ 的素因子有 $2$ 。

    考虑集合 $S_{1, 2}, S_{2, 1}, S_{2, 2}, S_{3, 1}, S_{3, 2}$,对这些集合用容斥原理(即求出 $[n]$ 中【不属于这些集合中的任一集合】的元素有多少个)即可求得 $f_i$ 。

    在对 $S_1, S_2, dots, S_n$ 用容斥原理时,若 $S_i subset S_j$($i e j$)则可将 $S_i$ 去掉。

    注意到 $S_{3,2}, S_{2, 2}$ 都是 $S_{1, 2}$ 的子集,所以有些子集是不用考虑的。实际上我们考虑
    $S_{1, 2}, S_{2, 1}, S_{3, 1}$ 即可。

    将 $i$ 的素因子个数记作 $c_i$。求解 $f_i$ 需要计算 $2^{c_i + c_{a_i} }$ 个集合的基数。

    机械地采用容斥原理其实做了很多重复计算。

    容斥原理涉及求一些集合的交集的基数,这些交集可表为 $S_{x, y}$ 其中 $x, y$ 都是若干个素数的乘积。

    设 $A, B$ 为一些质数的集合,$p_A, p_B$ 分别为其中元素的乘积($p_{emptyset} = 1$)。以下也将 $S_{p_A,p_B}$ 写作 $S_{A,B}$ 。

    在使用容斥原理时我们实际上是要求 $|S_{A,B}|$,注意到 $|S_{A,B}|$ 每次出现,其系数都是 $-1^{|A|+|B|}$,故我们考虑 $|S_{A,B}|$ 出现了多少次。易见,$|S_{A,B}|$ 出现在 $f_i$ 的表达式中当且 $p_Amid i$ 且 $p_B mid a_i$,故 $|S_{A,B}|$ 出现了 $|S_{A,B}|$ 次。因此有
    egin{equation}
    sum_i f_i = sum_{A,B} (-1)^{|A|+|B|} |S_{A,B}|^2
    end{equation}

    egin{equation}
    |S_{A,B}| =sum_i [p_A|i,\,p_B|a_i] = sum_{k} [p_B mid a_{kp_A}]
    end{equation}
    于是
    egin{equation}
    sum_i f_i = sum_{A,B} (-1)^{|A|+|B|} left( sum_{k} [p_B mid a_{kp_A}] ight)^2 label{E:3}
    end{equation}
    借助 Möbius 函数,eqref{E:3} 可写成
    egin{equation}
    sum_i f_i = sum_{x}mu(x) sum_y mu(y) left( sum_{k} [y mid a_{kx}] ight)^2
    end{equation}

    计算方法:枚举 $x$,枚举 $k$,枚举 $y$($y$ 是 $kx$ 的因子),为每个 $mu(y) e 0$ 的 $y$ 维护一个计数器,并将这些 $y$ 放入一个列表。

  • 相关阅读:
    冒泡排序和选择排序的根本差别在哪里?
    选择排序的3种语言实现方法(C java python)
    OVS中arp响应的流表的实现
    python 输出语句的写法
    haproxy + keepalived 实现网站高可靠
    nginx + keepalived 实现高可靠web网站
    实践:配置keepalived实现主备热备份功能
    Another app is currently holding the yum lock; waiting for it to exit 解决方法
    举例:使用XML库的方式,实现RPC通信
    openvswitch 2.7 安装过程记录 总结
  • 原文地址:https://www.cnblogs.com/Patt/p/9956260.html
Copyright © 2020-2023  润新知