HDU 5321 Beautiful Set 容斥 (看题解)

Posted cjlhy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5321 Beautiful Set 容斥 (看题解)相关的知识,希望对你有一定的参考价值。

HDU 5321

感觉有点抗拒这种题目, 看到就感觉自己不会写,其实就是个沙雕题, 感觉得找个时间练练这种题。

g[ i ] 表示gcd为 i 的倍数的方案数, f[ i ] 表示gcd为 i 的方案数, 然后先算g[ i ]然后直接容斥。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 258280327;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T &a, S b) a += b; if(a >= mod) a -= mod;
template<class T, class S> inline void sub(T &a, S b) a -= b; if(a < 0) a += mod;
template<class T, class S> inline bool chkmax(T &a, S b) return a < b ? a = b, true : false;
template<class T, class S> inline bool chkmin(T &a, S b) return a > b ? a = b, true : false;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n, a[N], cnt[N];

int F[N], Finv[N], inv[N];
int f[N], g[N];


void prepare() 
    F[0] = Finv[0] = inv[1] = 1;
    for(int i = 2; i < N; i++) inv[i] = 1LL * (mod - mod / i) * inv[mod % i] % mod;
    for(int i = 1; i < N; i++) F[i] = 1LL * F[i - 1] * i % mod;
    for(int i = 1; i < N; i++) Finv[i] = 1LL * Finv[i - 1] * inv[i] % mod;


inline int A(int n, int m) 
    if(n < 0 || n < m) return 0;
    return 1LL * F[n] * Finv[n - m] % mod;


inline int C(int n, int m) 
    if(n < 0 || n < m) return 0;
    return 1LL * F[n] * Finv[m] % mod * Finv[n - m] % mod;


int solve1() 
    for(int i = 1; i <= 100000; i++) 
        g[i] = 0;
        for(int j = 1; j <= cnt[i]; j++) 
            add(g[i], 1LL * A(cnt[i], j) * F[n - j + 1] % mod);
        
    
    int ans = 0;
    for(int i = 100000; i >= 1; i--) 
        f[i] = g[i];
        for(int j = i + i; j <= 100000; j += i) 
            sub(f[i], f[j]);
        
        add(ans, 1LL * i * f[i] % mod);
    
    return ans;



int solve2() 
    for(int i = 1; i <= 100000; i++) 
        g[i] = 0;
        for(int j = 1; j <= cnt[i]; j++) 
            add(g[i], 1LL * j * C(cnt[i], j) % mod);
        
    
    int ans = 0;
    for(int i = 100000; i >= 1; i--) 
        f[i] = g[i];
        for(int j = i + i; j <= 100000; j += i) 
            sub(f[i], f[j]);
        
        add(ans, 1LL * i * f[i] % mod);
    
    return ans;


void init() 
    for(int i = 1; i < N; i++) 
        cnt[i] = 0;
    


int main() 
    prepare();
    while(scanf("%d", &n) != EOF) 
        init();
        for(int i = 1; i <= n; i++) 
            scanf("%d", &a[i]);
            cnt[a[i]]++;
        
        for(int i = 1; i <= 100000; i++) 
            for(int j = i + i; j <= 100000; j += i) 
                cnt[i] += cnt[j];
            
        

        int ans1 = solve1();
        int ans2 = solve2();

        if(ans1 == ans2) 
            printf("Equal %d\n", ans1);
        
        else if(ans1 > ans2) 
            printf("Mr. Zstu %d\n", ans1);
        
        else 
            printf("Mr. Hdu %d\n", ans2);
        
    
    return 0;


/*
*/

 

以上是关于HDU 5321 Beautiful Set 容斥 (看题解)的主要内容,如果未能解决你的问题,请参考以下文章

hdu4872 Beautiful Soup 模拟

hdu 4781 Beautiful Soup 构造

HDU 4782 Beautiful Soup(模拟)

HDU5179 beautiful number 题解 数位DP

hdu 4888 Redraw Beautiful Drawings(最大流,判环)

hdu4888 Redraw Beautiful Drawings(最大流)