HDU 5321 Beautiful Set

题目链接 我们可以枚举子集的大小k,求出所有大小为k的子集对答案的贡献,,问题就解决了。

;ll;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\n”, ans1);else {if (ans1 < ans2)printf(“Mr. Hdu %d\n”, ans2);elseprintf(“Equal %d\n”, 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;}

有时间,我们可以去爬山,

HDU 5321 Beautiful Set

相关文章:

你感兴趣的文章:

标签云: