zoukankan      html  css  js  c++  java
  • hdu5321 beautiful set(莫比乌斯反演)

    (cnt[i])为权值为i的倍数的数的数量。
    (f0[i],f1[i])分别为两种方法(gcd=i)的贡献是i的多少倍。
    (F0[i],F1[i])分别为两种方法(gcd)(i)的倍数的贡献是i的多少倍。
    (F0[i]=sum_{j=1}^{cnt[i]}A_{cnt[i]}^{cnt[i]-j}*(n-j)!*(n-j+1))
    (F1[i]=sum_{j=1}^{cnt[i]}j*C_{cnt[i]}^{j})
    然后显然有(F[i]=sum_{dmid i}f[d])
    然后莫比乌斯反演一下

    [f(n)=∑_{nmid d}μ(frac{d}{n})F(d) ]

    复杂度调和级数(O(nlnn))

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define int long long
    const int N=101000;
    const int p=258280327;
    bool book[N];
    int prime[N],mu[N],fac[N],inv[N],num;
    int a[N],F0[N],f0[N],F1[N],f1[N],mx,cnt[N],T,n;
    int read(){
        int sum=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
        return sum*f;
    }
    void init(){
        for(int i=0;i<=100000;i++)
            cnt[i]=a[i]=f1[i]=f0[i]=F1[i]=F0[i]=0;
    }
    int ksm(int x,int b){
        int tmp=1;
        while(b){
            if(b&1)tmp=tmp*x%p;
            x=x*x%p;
            b>>=1;
        }
        return tmp;
    }
    int A(int n,int m){
        return fac[n]*inv[n-m]%p;
    }
    int C(int n,int m){
        return fac[n]*inv[n-m]%p*inv[m]%p;
    }
    void pre_work(){
        mu[1]=1;
        for(int i=2;i<=100000;i++){
            if(book[i]==0){
                prime[++num]=i;
                mu[i]=-1;
            }
            for(int j=1;j<=num&&prime[j]*i<=100000;j++){
                book[i*prime[j]]=1;
                if(i%prime[j]==0)break;
                mu[prime[j]*i]=-mu[i];
            }
        }
        fac[0]=1;
        for(int i=1;i<=100000;i++)fac[i]=(fac[i-1]*i)%p;
        inv[100000]=ksm(fac[100000],p-2);
        for(int i=99999;i>=0;i--)inv[i]=inv[i+1]*(i+1)%p;
    }
    signed main(){
        pre_work();
        while(scanf("%lld",&n)!=EOF){
            init();
            for(int i=1;i<=n;i++)a[read()]++;
            for(int i=1;i<=100000;i++)
                for(int j=i;j<=100000;j+=i)cnt[i]+=a[j];
            for(int i=1;i<=100000;i++)
                for(int j=1;j<=cnt[i];j++)
                    F0[i]=(F0[i]+A(cnt[i],j)*fac[n-j+1])%p,
                    F1[i]=(F1[i]+C(cnt[i],j)*j)%p;
            for(int i=1;i<=100000;i++)
                for(int j=i;j<=100000;j+=i)
                    f0[i]=(f0[i]+mu[j/i]*F0[j])%p,
                    f1[i]=(f1[i]+mu[j/i]*F1[j])%p;
            int ans1=0,ans2=0;
            for(int i=1;i<=100000;i++)
                ans1=(ans1+f0[i]*i)%p,
                ans2=(ans2+f1[i]*i)%p;
            if(ans1>ans2)printf("Mr. Zstu %lld
    ",ans1);
            else if(ans1<ans2)printf("Mr. Hdu %lld
    ",ans2);
            else printf("Equal %lld
    ",ans2);
        }
        return 0;
    }
    
  • 相关阅读:
    http协议学习系列
    git常用命令大全
    git常用命令与常见面试题总结
    MyBatis框架及原理分析
    Mybatis常见面试题总结
    java实现克隆的三种(很最全面)
    java中equals和==之间的区别?clone方法的作用,及其为什么要使用clone方法?如何使用clone复制对象?以及深克隆浅克隆
    ThreadLocal的简单使用及实现的原理
    Java 最常见的 208 道面试题
    TCP流量控制
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/10253399.html
Copyright © 2011-2022 走看看