题目:https://www.acwing.com/problem/content/233/

题意:给你n个不同的数,让你选取一个四元组,gcd为1,让你求这样的四元组数量是多少

思路:我们单独直接去算肯定不行,正难反易,我们可以用总的减去其他gcd不是1的,也就是四个数同时有一个相同且不是1的因子,然后我们按gcd值分组

但是中间有很多分组其实有重复的值,比如  2,3  那么 6就是他们重复的,这个题不能n^2过,我们只能拆每个数的因子,然后用这些因子构造出其他与当前

数构造出不是1因子的个数

#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define maxn 100005
using namespace std;
ll n,a[maxn],cnt;
int vis[maxn];
int flag[maxn];
ll prime[maxn];
ll C(ll n,ll m){
return n*(n-)*(n-)*(n-)/;
}
void make(ll x){
cnt=;
for(int i=;i*i<=x;i++){
if(x%i==){
prime[cnt++]=i;
while(x%i==) x/=i;
}
}
if(x>) prime[cnt++]=x;
for(int i=;i<(<<cnt);i++){
ll cur=;
ll num=;
for(int j=;(i>>j)>;j++){
if((i>>j)&){
num++;
cur*=prime[j];
}
}
vis[cur]++;
flag[cur]=num;
}
}
int main()
{
while(scanf("%lld",&n)!=EOF){
memset(vis,,sizeof(vis));
memset(flag,,sizeof(flag));
for(int i=;i<n;i++){
scanf("%lld",&a[i]);
make(a[i]);
}
ll sum=C(n,);
for(int i=;i<=;i++){
if(flag[i]&){
sum-=C(vis[i],);
}
else{
sum+=C(vis[i],);
}
}
printf("%lld\n",sum);
}
}

最新文章

  1. Android中通信协议
  2. 配置VMware虚拟机用绕过校园网达到无线上网配置方法
  3. 隐藏 input 标签的边框
  4. burpsuite绕过本地javascripte上传文件
  5. 初始化IoC容器(Spring源码阅读)-我们到底能走多远系列(31)
  6. 使用py2exe打包你的py程序
  7. [Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server 不存在或访问被拒绝
  8. KDE声音服务器 arts
  9. ios固定高度禁止惯性滚动
  10. .NET基础拾遗(7)多线程开发基础2
  11. Qt Assistant 的配置文件qhp---&gt;qch 和qhcp---&gt;qhc详解与生成
  12. js之form表单的获取
  13. Hadoop集群的安装与配置(centos 6.5)
  14. JAVA和C++区别
  15. Java8之旅(六) -- 使用lambda实现尾递归
  16. java基本数据类型的包装类
  17. Java作业六(2017-10-30)
  18. transform的兼容性写法浏览器 和 transition
  19. Shell脚本应用(for、while循环语句和case分支语句)
  20. 7. 反转整数(Reverse Integer) C++

热门文章

  1. 简记 jQuery 插件模板
  2. 2018-2019-2 20175203 实验四《Android 开发基础》
  3. 如何在vue里面调用高德地图
  4. Tecplot 360 安装后弹出“Is your Tecplot 360 EX liense valid?”解决方法
  5. vlc 学习网
  6. java多线程学习笔记(六)
  7. Scrapy框架: 通用爬虫之SitemapSpider
  8. SSM+Maven使用PageHelper插件分页
  9. Linux安装篇超详细
  10. go语言从例子开始之Example14.变参函数