zoukankan      html  css  js  c++  java
  • HDU 5321 Beautiful Set

    题目链接
    我们能够枚举子集的大小k。求出全部大小为k的子集对答案的贡献。问题就攻克了。
    注意到欧拉函数的性质:n=φ(d),d|n
    莫比乌斯函数性质:d|nμ(d)=0n>1
    感谢http://blog.csdn.net/u013368721/article/details/47125353

    #include <bits/stdc++.h>
    using namespace std;
    #define prt(k) cerr<<#k" = "<<k<<endl
    typedef long long ll;
    typedef long long LL;
    const ll inf = 0x3f3f3f3f;
    const int mod = 258280327;
    int exgcd(int a, int b, int &x, int &y)
    {
        if (b == 0) {
            x = 1; y = 0; return a;
        } else {
            int d = exgcd(b, a%b, y, x);
            y -= a/b * x;
            return d;
        }
    }
    int inv(int a)
    {
        int x, y, b = mod;
        exgcd(a, b, x, y);
        if (x < 0) x += mod;
        return x;
    }
    const int N = 102333;
    int phi[N];
    int fac[N], vf[N];
    void init()
    {
        fac[0] = 1;
        vf[0] = 1;
        for (int i=1;i<N;i++) {
            phi[i] = i;
            fac[i] = (LL) fac[i - 1] * i % mod;
            vf[i] = inv(fac[i]);
        }
        for (int i=2;i<N;i++) if (phi[i]==i) {
            for (int j=i;j < N; j+=i)
                phi[j] = phi[j] / i * (i - 1);
        }
    }
    int C(int n, int m)
    {
        return (LL) fac[n] * vf[m] % mod * vf[n - m] % mod;
    }
    int cnt[N];
    int n;
    int id[N];
    bool cmp(int a, int b)
    {
        return cnt[a] > cnt[b];
    }
    // cnt[i] : i 的倍数有多少个
    void solve()
    {
        int ans1 = 0, ans2 = 0;
        for (int i=1;i<N;i++) {
            int tmp = 0;
            for (int j=1;j<N && cnt[id[j]]>=i;j++) {
                int idx = id[j];
                int t = (LL) C(cnt[idx],i) * phi[idx] % mod;
                tmp = (tmp + t) % mod;
            }
            ans2 = (ans2 + (LL) i * tmp % mod) % mod;
            tmp = (LL) tmp * fac[i] % mod * fac[n-i+1] % mod;
            ans1 = (ans1 + tmp) % mod;
        }
        if (ans1 > ans2) printf("Mr. Zstu %d
    ", ans1);
        else {if (ans1 < ans2)
            printf("Mr. Hdu %d
    ", ans2);
            else
                printf("Equal %d
    ", ans1);
        }
    }
    int main()
    {
        init();
        while (scanf("%d", &n)==1) {
            memset(cnt, 0 ,sizeof cnt);
            for (int i=0;i<n;i++) {
                int x; scanf("%d", &x);
                cnt[x] ++;
            }
            for (int i=1;i<N;i++) {
                id[i] = i;
                for (int j=i+i;j<N;j+=i) {
                    cnt[i] += cnt[j];
                }
            }
            sort(id+1, id+N, cmp);
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    element多选下拉框的坑
    滚动条样式全局修改
    element表格自带排序的坑
    c++学习
    HTTP与TCP的区别和联系
    JSP整理
    学习目标
    mysql操作
    JAVA Date、String、Calendar类型之间的转化
    后台数据类型接收问题总结
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7283555.html
Copyright © 2011-2022 走看看