LightOJ 1161 - Extreme GCD (给你n个数 让你找出4个数使得这四个数最大公约数为1 有多少种) (容斥)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LightOJ 1161 - Extreme GCD (给你n个数 让你找出4个数使得这四个数最大公约数为1 有多少种) (容斥)相关的知识,希望对你有一定的参考价值。
题意:http://www.lightoj.com/volume_showproblem.php?problem=1161
给你n个数 让你找出四个数 并且这四个数的最大公约数为1 问有多少种
正难则反 我们去考虑其补集 我们求出四个数的最大公约数大于1的 然后再用C(n,4)减去 剩下的就是结果
我们将每个数的因子都分解出来,就好比7个数 2,3,4,6,6,12,24
可得a[1]=7;a[2]=6;a[3]=5;a[4]=3;a[6]=4;a[8]=1;a[12]=2;a[24]=1;
从大到小 很显然在最大公约数为6的情况下有1种
同理为3有5种,为2有15种 为1的也就是全部有35种
很显然在为6的情况 重复在为3 和为2里面出现 所以我们要减去
即为3的时候有4种 为2有14种 为6有1种
所以满足的也就是16=35-4-14-1;
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<vector> #include<math.h> #include<string> using namespace std; #define INF 0x3f3f3f3f #define LL long long #define N 10006 #define Lson rood<<1 #define Rson rood<<1|1 LL a[N]; LL ans[N]; void q(int x) { for(int i=1;i*i<=x;i++) {///每个因子 只遍历一边 if(x%i==0) { a[i]++; if(i*i!=x) a[x/i]++; } } } LL qq(LL x) { return x*(x-1)*(x-2)*(x-3)/24; } int main() { int T,t=1; scanf("%d",&T); while(T--) { int n,d; memset(a,0,sizeof(a)); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&d); q(d); } for(int i=10000;i>=1;i--) { ans[i]=qq(a[i]); for(int j=i*2;j<=10000;j+=i) ans[i]-=ans[j]; } printf("Case %d: %lld\n",t++,ans[1]); } return 0; }
以上是关于LightOJ 1161 - Extreme GCD (给你n个数 让你找出4个数使得这四个数最大公约数为1 有多少种) (容斥)的主要内容,如果未能解决你的问题,请参考以下文章
UVA - 11426 GCD - Extreme (II) (欧拉函数)