HDU5514(容斥)

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
#define maxn 1111111

long long n, m;
vector <long long> fac;
long long a[maxn], b[maxn];
int vis[maxn];
long long ans = 0;

void fenjie ()
{
    fac.clear ();
    long long num = m;
    for (long long i = 2; i*i <= num; i++)
    {
        if (num%i == 0)
        {
            fac.push_back (i);
            if (num/i != i) fac.push_back (num/i);
        }
    }
    sort (fac.begin (), fac.end ());
}

long long f (long long num)
{
    long long last = (m-1)/num;
    return (last+1)*last*num/2;
}

long long lcm (long long a, long long b) {
    long long  g = __gcd (a, b);
    long long ans = a*b/g;
    return ans;
}

void dfs (int pos, long long LCM, int cnt) {
    if (pos == n) {
        if (cnt&1) {
            ans += f (LCM);
        }
        else if (cnt)
            ans -= f (LCM);
        return ;
    }
    if (LCM%a[pos] == 0)
        return ;
    dfs (pos+1, LCM, cnt);
    LCM = lcm (LCM, a[pos]);
    dfs (pos+1, LCM, cnt+1);
}

void solve ()
{
    fenjie ();
    ans = 0;
    memset (vis, 0, sizeof vis);
    dfs (0, 1, 0);
    printf ("%lld\n", ans);
    return ;
}

int main ()
{
    //freopen ("in", "r", stdin);
    ios::sync_with_stdio (0);
    int t, kase = 0;
    cin >> t;
    while (t--)
    {
        printf ("Case #%d: ", ++kase);
        cin >> n >> m;
        memset (a, 0, sizeof a);
        for (int i = 0; i < n; i++)
        {
            cin >> b[i];
            a[i] = __gcd (m, b[i]);
        }
        sort (a, a+n);
        n = unique (a, a+n)-a; //删除重复元素
        if (a[n-1] == m) n--;
        if (a[0] == 1)
        {
            printf ("%lld\n", (m-1)*m/2);
            continue;
        }
        solve ();
    }
    return 0;
}

你可能感兴趣的:(HDU5514(容斥))