51nod 1616 最小集合
来源:互联网 发布:收款收据打印软件 编辑:程序博客网 时间:2024/06/05 09:17
51 nod 1616 最小集合
原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1616
题目的意思更一般的可以理解为:
任取一些数字。它们可能出现的最大公约数。包括原始给定的数字,一共可以出现多少不同的数字。
因为:d=gcd(x,y)t=gcd(d,c)t=gcd(x,y,c)
记:确定出现的数字中。n 的倍数的个数为C[n]
那么:gcd(i,j)=d 的(i,j) 对数的个数为,其中,i,j 均为已确定数字集合中的数字。:f(d)=∑[gcd(i,j)=d]F(d)=∑d|af(a)=∑d|i∑d|j1=C[d](C[d]−1)f(d)=∑d|aμ(ad)F(d)
我们从大到小计算可能出现的数字。因为没有出现的数字只可能从更大的数字产生。所以不回漏掉。
注意。如果产生了新的数字。记得更新C 数组。(我就是忘记更新。debug 了很久)
#include <algorithm>#include <string.h>#include <stdio.h>#include <vector>#define MAXN 1000005using namespace std;typedef long long LL;LL C[MAXN];int cnt[MAXN];int mu[MAXN]={0,-1};int main (){ for(int i=1;i<MAXN;i++) { mu[i]=-mu[i]; for(int j=i<<1;j<MAXN;j+=i)mu[j]+=mu[i]; } int n,a; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a),cnt[a]=1; int ans=0; for(int i=MAXN-1;i;i--) { LL u=0; for(int j=i;j<MAXN;j+=i)C[i]+=cnt[j]; if(!C[i])continue; for(int j=i,k=1;j<MAXN;j+=i,k++)u+=(LL)mu[k]*(((C[j]-1)*C[j])>>1ll); if(u>0||cnt[i]) { ans++; if(!cnt[i])C[i]++; cnt[i]=1; } } printf("%d\n",ans); return 0;}
阅读全文
0 0
- 51nod 1616 最小集合
- 51nod 1616 最小集合
- 51nod-1616 最小集合
- 51Nod-1616-最小集合
- 51nod 1616 最小集合
- 51nod 1616 最小集合
- 51nod 最小集合
- 51 Nod 1616——最小集合
- 【51NOD 1616】【51NOD 算法马拉松19】最小集合
- [暴力 乱搞] 51Nod 1616 算法马拉松19 B 最小集合
- [51nod月赛19B]最小集合
- 51nod算法马拉松19 B 最小集合
- 集合计数 51Nod
- 51NOD 1283 最小周长
- 51nod 1283 最小周长
- 51 nod 1283 最小周长
- 51nod 1283 最小周长
- 51NOD 1283 最小周长
- [Unity框架]PureMVC基础
- 链表中环的入口点
- bug解决-内核C库写保护(FORTIFY: write: prevented read past end of buffer)
- vector动态数组邻接表--功能更强大的邻接表
- CXF生成客户端代码并打包成jar文件
- 51nod 1616 最小集合
- 嵌入式 GCC或者G++编译优化选项
- 稳定排序和不稳定排序
- 工作的轻重缓急
- .nte连接数据库常见问题,Unknown column '张三' in 'where clause'
- DSP28335笔记--SCI篇
- 误差反向传播算法浅解
- Load denied by X-Frame-Options: does not permit cross 解决办法
- java项目数据库乱码的解决办法