【POJ 3904】 Sky Code

【题目链接】

            http://poj.org/problem?id=3904

【算法】

           问题可以转化为求总的四元组个数 - 公约数不为1的四元组个数

           总的四元组个数为C(n,4),公约数不为1的四元组个数可以用容斥原理求

【代码】

           

#include <algorithm>  
#include <bitset>  
#include <cctype>  
#include <cerrno>  
#include <clocale>  
#include <cmath>  
#include <complex>  
#include <cstdio>  
#include <cstdlib>  
#include <cstring>  
#include <ctime>  
#include <deque>  
#include <exception>  
#include <fstream>  
#include <functional>  
#include <limits>  
#include <list>  
#include <map>  
#include <iomanip>  
#include <ios>  
#include <iosfwd>  
#include <iostream>  
#include <istream>  
#include <ostream>  
#include <queue>  
#include <set>  
#include <sstream>  
#include <stdexcept>  
#include <streambuf>  
#include <string>  
#include <utility>  
#include <vector>  
#include <cwchar>  
#include <cwctype>  
#include <stack>  
#include <limits.h>
using namespace std;
#define MAXN 10010
typedef long long ll;

ll i,j,n;
ll all,ans;
ll a[MAXN];
ll cnt[MAXN];
vector< ll > num[MAXN];

inline ll C(ll n,ll m)
{
        ll i;
        ll ret = 1;
        if (n < m) return 0;
        if (m == 0) return 1;
        for (i = n; i >= n - m + 1; i--) ret *= i;
        for (i = 1; i <= m; i++) ret /= i;
        return ret;         
}
inline void init()
{
        ll i,j,tmp,s;
        bool flag;
        for (i = 2; i <= MAXN; i++)
        {
                tmp = i;
                s = 0;
                flag = false;
                for (j = 2; j <= sqrt(i); j++)
                {
                        if (tmp % j == 0)
                        {
                                if (tmp % (j * j) == 0)
                                {
                                        flag = true;
                                        break;
                                }
                                while (tmp % j == 0) 
                                        tmp /= j;
                                s++;
                        }
                }
                if (tmp > 1) s++;
                if (!flag) num[s].push_back(i);
        }
}
int main() 
{
        
        init();
        while (scanf("%lld",&n) != EOF)
        {
                all = C(n,4);
                ans = 0;
                memset(cnt,0,sizeof(cnt));
                for (i = 1; i <= n; i++) scanf("%lld",&a[i]);
                for (i = 1; i <= n; i++)
                {
                        for (j = 1; j <= sqrt(a[i]); j++)
                        {
                                if (a[i] % j == 0)
                                {
                                        cnt[j]++;
                                        if (j * j != a[i]) cnt[a[i]/j]++;
                                }
                        }
                }
                for (i = 1; i < MAXN; i++)
                {
                        for (j = 0; j < num[i].size(); j++)
                        {
                                if (i & 1) ans += C(cnt[num[i][j]],4);
                                else ans -= C(cnt[num[i][j]],4); 
                        }
                }
                printf("%lld\n",all - ans);
        }
        
        return 0;
    
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9301351.html
sky