zoukankan      html  css  js  c++  java
  • P2714 四元组统计

    题目描述

    (n)个正整数(a_i),你要统计有多少个四元组满足(mathrm{gcd}(a_i,a_j,a_k,a_l) = 1)

    题解

    这道题思路很显然,就是枚举(gcd)的思路。

    我们用(f[x])表示(x)以及(x)的倍数的出现次数,输入时先把该数的出现次数统计了,然后可以(O(n*ln n))加上他的倍数的出现次数。

    然后考虑答案的计算。

    如果(gcd)(x)或者(x)的倍数的话,方案数显然是(frac{f[x] * (f[x] - 1) * (f[x] - 2) * (f[x] - 3)}{24})(由于同一种选择随意排列有(4!=24)种情况,所以除以(24))。

    那么转化成(gcd)(x)的方案数,我们就需要简单容斥一下,减去(gcd)(2*x,3*x...k*x)的方案数,所以我们倒着循环,就可以再次在(O(n*ln n))的时间统计了。

    #include <iostream>
    #include <cstdio>
    #define ll long long
    using namespace std;
    const int N = 1e4 + 5;
    int mx, n;
    ll f[N];
    inline int read()
    {
    	int x = 0, f = 1; char ch = getchar();
    	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    	return x * f;
    }
    void work()
    {
    	while(scanf("%d", &n) != EOF)
    	{
    		for(int i = 1; i <= mx; i ++) f[i] = 0; mx = 0;
    		for(int i = 1, x; i <= n; i ++) {x = read(); f[x] ++; mx = max(mx, x);}
    		for(int i = 1; i <= mx; i ++) for(int j = 2 * i; j <= mx; j += i) f[i] += f[j];
    		for(int i = mx; i >= 1; i --)
    		{
    			f[i] = f[i] * (f[i] - 1) * (f[i] - 2) * (f[i] - 3) / 24;
    			for(int j = 2 * i; j <= mx; j += i) f[i] -= f[j];
    		}
    		printf("%lld
    ", f[1]);
    	}
    }
    int main() {return work(), 0;}
    
  • 相关阅读:
    jquery从零开始(一)
    Android第三次作业
    Android第一次作业
    团队作业-项目答辩
    软工第二次作业
    软工团队第二次作业
    bug killer 团队
    软件工程第一次作业
    Android第四次作业
    Android第三次作业
  • 原文地址:https://www.cnblogs.com/Sunny-r/p/12599717.html
Copyright © 2011-2022 走看看