zoukankan      html  css  js  c++  java
  • 【CodeForces】585 E. Present for Vitalik the Philatelist

    【题目】E. Present for Vitalik the Philatelist

    【题意】给定n个数字,定义一种合法方案为选择一个数字Aa,选择另外一些数字Abi,令g=gcd(Ab1...Abx),要求满足g≠1且gcd(Aa,g)=1,求方案数取模1e9+7。2<=n<=5*10^5,2<=ai<=10^7。

    【算法】数论,计数问题

    【题解】

    考虑选择一些数字使得g≠1,容易想到枚举g值,O(n ln n)地枚举g的倍数,得到b[g]表示数列中数字为g的倍数的个数。

    那么含有公因数g的区间数为2^b[g]-1,考虑容斥。

    引入莫比乌斯函数μ(x),简单定义:μ(1)=1,含奇数个素因子μ(x)=-1,含偶数个素因子μ(x)=1,含重复素因子μ(x)=0。

    根据容斥原理的奇加偶减,应将-μ[g]作为系数,那么总方案数就是sum=Σ-μ(g)*(2^b[g]-1),g=2~max(ai)。

    接下来考虑区间和数字Aa组合,会减去gcd和Aa不互质的区间,也就是去掉公因数含有Aa的素因子的区间,这实际上也是莫比乌斯函数容斥。

    所以可以套用在原来的容斥上,也就是对于数字Aa,只要将Aa的所有因子g的μ(g)视为0,计算出来的sum就是数字Aa的贡献。

    那么再换个角度,含有公因数g的区间只会在数字Aa不含因子g的时候被贡献,这样的数字数实际上是n-b[g]。

    所以,ans=Σ-μ(g)*(2^b[g]-1)*(n-b[g]),g=2~max(ai)。

    最后,可以用自带容斥的方法避开μ的计算。最后视为对(2^b[g]-1)*(n-b[g])进行容斥(即使这样容斥没有实际含义),然后减去f[h](h=k*g),得到f[g]。ans=Σf[g]。(这种方法和埃式筛μ的本质相同)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=500010,N=10000010,M=1e9+7;
    int n,x,b[N],fx[maxn],f[N],ans=0,mx=0;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&x),mx=max(mx,x),b[x]++;
        fx[0]=1;for(int i=1;i<=n;i++)fx[i]=(fx[i-1]<<1)%M;
        for(int g=mx;g>=1;g--){
            x=b[g];
            for(int i=g+g;i<=mx;i+=g){
                x+=b[i];
                f[g]=(f[g]-f[i]+M)%M;
            }
            if(g!=1){
                f[g]=(f[g]+1ll*(fx[x]-1)*(n-x)%M)%M;
                ans=(ans+f[g])%M;
            }
        }
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    集合---Map
    一个机器部署多个tomcat
    JavaScript要不要加分号";"
    Nodejs 路径 /, ./, ../, ..// 的区别
    玩转Vue的24个小程序---基础篇
    如何创建Node.js Web服务器
    为什么Ajax XMLHttpRequest POST方法传递参数失败了
    字典元素如何遍历
    Beautiful Soup 如何获取到href
    如何查看Ajax请求
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7944328.html
Copyright © 2011-2022 走看看