[Codeforces 364D]Ghd(随机算法+gcd)
[Codeforces 364D]Ghd(随机算法)
题面
给出n个正整数,在其中选出n/2(向上取整)个数,要求这些数的最大公约数最大,求最大公约数的最大值
分析
每个数被选到的概率$\geq \frac{1}{2}$,因此每次随机选出一个数x,选k次,对于每个数处理出它所能得到的最大答案。显然最大公约数一定是x的一个因数,我们看看x的哪个因数可以成为这n/2(向上取整)个数的gcd。
先对x进行因数分解。并求出x与所有a[i]的gcd ,看看哪个因数成为x和a[i]的gcd的次数最多,且次数超过n/2 。具体做法是,对于每个因数d[u],记录满足gcd(x,a[i])=d[u]的i的个数cnt[u]。然后对于两个因数d[i],d[j] (d[i]<d[j]),如果d[i]能整除d[j],说明j对应的数字也可以被这个的整除,应当把cnt[j]加到cnt[i]上 。最后扫描cnt数组,如果cnt[i]*2>n,就更新答案
这样的时间复杂度是$O(k(n\log max(a_i)+\sqrt{max(a_i)}+max(\sigma(a_i)^2) \ )\(,其中\)\sigma_(a_i)$为$a_i$的因数个数。
我们随机取k次,这k个数都不在最终答案的集合的概率为$1-2^{-k}$,经过实验,取k=10的时候能较好的平衡时间复杂度和正确概率。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#define maxn 1000000
#define maxt 10 //随机选数次数
using namespace std;
typedef long long ll;
int n;
ll a[maxn+5];
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
int random(int l,int r){
return (long long )rand()*rand()%(r-l+1)+l;
}
int sz=0;
ll d[maxn+5];
int cnt[maxn+5];
void divide(ll x){
sz=0;
for(ll i=1;i*i<=x;i++){
if(x%i==0){
d[++sz]=i;
if(x/i!=i) d[++sz]=x/i;
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
ll ans=0;
for(int cas=1;cas<=maxt;cas++){
/*
每个数有1/2的概率被选中,随机t个数,假设它被选中,求出选中它时的答案
对随机出的数x分解因数,并求出x与所有a[i]的gcd
看看哪个因数成为x和a[i]的gcd的次数最多,且次数超过n/2
对于求出来的公因数,我们去从大到小找一个会成为超过一半数的因数的数字。
具体做法是,选择一个因数,去找比它大的因数,
如果它能整除大因数,说明大因数对应的数字也可以被这个小因数整除,应当把加到这个小因数的计数上
时间复杂度O(n+d^2)
但d很小,所以不会TLE
*/
ll x=a[random(1,n)];
divide(x);
sort(d+1,d+sz+1);
for(int i=1;i<=sz;i++) cnt[i]=0;
for(int i=1;i<=n;i++){
int pos=lower_bound(d+1,d+1+sz,gcd(a[i],x))-d;
cnt[pos]++;
}
for(int i=1;i<=sz;i++){
for(int j=i+1;j<=sz;j++){
if(d[j]%d[i]==0) cnt[i]+=cnt[j];
}
}
for(int i=sz;i>=1;i--){
if(cnt[i]*2>=n){
ans=max(ans,d[i]);
break;
}
}
}
printf("%I64d\n",ans);
}
/*
2
11111111111
11111111111
*/
[Codeforces 364D]Ghd(随机算法+gcd)的更多相关文章
- Codeforces 1114E(数学+随机算法)
题面 传送门 分析 通过二分答案,我们显然可以求出数组中最大的数,即等差数列的末项 接着随机取一些数组中的数,对他们两两做差,把得到的差取gcd即为公差 例a={1,5,9,13},我们随机取了1 9 ...
- 随机算法 - Miller_Rabin pollard_rho
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #in ...
- 微信红包中使用的技术:AA收款+随机算法
除夕夜你领到红包了吗?有的说“我领了好几K!”“我领了几W!” 土豪何其多,苦逼也不少!有的说“我出来工作了,没压岁钱了,还要发红包”.那您有去抢微信红包吗?微信群中抢“新年红包”春节爆红.618微信 ...
- POJ 3318 Matrix Multiplication(随机算法)
题目链接 随机算法使劲水...srand((unsigned)time(0))比srand(NULL)靠谱很多,可能是更加随机. #include <cstdio> #include &l ...
- 抽奖随机算法的技术探讨与C#实现
一.模拟客户需求 1.1 客户A需求:要求每次都按照下图的概率随机,数量不限,每个用户只能抽一次,抽奖结果的分布与抽奖概率近似. 1.2 客户B需求:固定奖项10个,抽奖次数不限,每个用户只能抽一次, ...
- hdu 4712 (随机算法)
第一次听说随机算法,在给的n组数据间随机取两个组比较,当随机次数达到一定量时,答案就出来了. #include<stdio.h> #include<stdlib.h> #inc ...
- 权重随机算法的java实现
一.概述 平时,经常会遇到权重随机算法,从不同权重的N个元素中随机选择一个,并使得总体选择结果是按照权重分布的.如广告投放.负载均衡等. 如有4个元素A.B.C.D,权重分别为1.2.3.4,随机结果 ...
- hdu 4712 Hamming Distance ( 随机算法混过了 )
Hamming Distance Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- HDU4712+随机算法
随机算法 求n个20位的2进制串的MinDist. Dist:两个串的异或结果中1的个数 /* 随机算法 */ #include<algorithm> #include<iostre ...
随机推荐
- adb 链接网络 connect 安装apk install 断开IP链接 kill-server 连接数devices
https://blog.csdn.net/zhonglunshun/article/details/78362439 ./adb connetc 192.168.1.11 ./adb install ...
- JavaScript中的垃圾收集机制
JavaScript 具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存. 在编写 JavaScript 程序时,开发人员不用再关心内存使用问题,所需内存的分配以及无用内存的 ...
- 330-基于FMC接口的Kintex-7 XC7K325T PCIeX8 3U PXIe接口卡 光纤PCIe卡
一.板卡概述 本板卡基于Xilinx公司的FPGAXC7K325T-2FFG900 芯片,pin_to_pin兼容FPGAXC7K410T-2FFG900 ,支持PCIeX8.64bit D ...
- hdu 4082 Hou Yi's secret(暴力枚举)
Hou Yi's secret Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 【LeetCode】哈希表 hash_table(共88题)
[1]Two Sum (2018年11月9日,k-sum专题,算法群衍生题) 给了一个数组 nums, 和一个 target 数字,要求返回一个下标的 pair, 使得这两个元素相加等于 target ...
- idea hibernate console 执行hql报错
报错信息 hql> select a from GDXMZD a[2019-08-29 13:45:01] org.hibernate.service.spi.ServiceException: ...
- thread.join() 阻塞原理分析
参考: https://blog.csdn.net/u010983881/article/details/80257703
- hadoop中的一些术语介绍
1.MR作业是客户端执行的一个工作单元:包括输入数据,MR的程序和配置信息. Hadoop将作业分成若干个任务task来执行,分为两种任务:map和reduce任务.这些任务运行在集群的节点上,并通过 ...
- 用于理解C++右值引用的例子
#include <iostream> using namespace std; void printReference (int& value) { cout << ...
- handy源码阅读(一):EventBase类
类EventBase继承于类EventBases,继承于noncopyable. 其中noncopyable是一个去除了拷贝构造和赋值构造的类. noncopyable: class noncopy ...