[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的时候能较好的平衡时间复杂度和正确概率。

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cstdlib>
  6. #include<ctime>
  7. #define maxn 1000000
  8. #define maxt 10 //随机选数次数
  9. using namespace std;
  10. typedef long long ll;
  11. int n;
  12. ll a[maxn+5];
  13. ll gcd(ll a,ll b){
  14. return b==0?a:gcd(b,a%b);
  15. }
  16. int random(int l,int r){
  17. return (long long )rand()*rand()%(r-l+1)+l;
  18. }
  19. int sz=0;
  20. ll d[maxn+5];
  21. int cnt[maxn+5];
  22. void divide(ll x){
  23. sz=0;
  24. for(ll i=1;i*i<=x;i++){
  25. if(x%i==0){
  26. d[++sz]=i;
  27. if(x/i!=i) d[++sz]=x/i;
  28. }
  29. }
  30. }
  31. int main(){
  32. scanf("%d",&n);
  33. for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
  34. ll ans=0;
  35. for(int cas=1;cas<=maxt;cas++){
  36. /*
  37. 每个数有1/2的概率被选中,随机t个数,假设它被选中,求出选中它时的答案
  38. 对随机出的数x分解因数,并求出x与所有a[i]的gcd
  39. 看看哪个因数成为x和a[i]的gcd的次数最多,且次数超过n/2
  40. 对于求出来的公因数,我们去从大到小找一个会成为超过一半数的因数的数字。
  41. 具体做法是,选择一个因数,去找比它大的因数,
  42. 如果它能整除大因数,说明大因数对应的数字也可以被这个小因数整除,应当把加到这个小因数的计数上
  43. 时间复杂度O(n+d^2)
  44. 但d很小,所以不会TLE
  45. */
  46. ll x=a[random(1,n)];
  47. divide(x);
  48. sort(d+1,d+sz+1);
  49. for(int i=1;i<=sz;i++) cnt[i]=0;
  50. for(int i=1;i<=n;i++){
  51. int pos=lower_bound(d+1,d+1+sz,gcd(a[i],x))-d;
  52. cnt[pos]++;
  53. }
  54. for(int i=1;i<=sz;i++){
  55. for(int j=i+1;j<=sz;j++){
  56. if(d[j]%d[i]==0) cnt[i]+=cnt[j];
  57. }
  58. }
  59. for(int i=sz;i>=1;i--){
  60. if(cnt[i]*2>=n){
  61. ans=max(ans,d[i]);
  62. break;
  63. }
  64. }
  65. }
  66. printf("%I64d\n",ans);
  67. }
  68. /*
  69. 2
  70. 11111111111
  71. 11111111111
  72. */

[Codeforces 364D]Ghd(随机算法+gcd)的更多相关文章

  1. Codeforces 1114E(数学+随机算法)

    题面 传送门 分析 通过二分答案,我们显然可以求出数组中最大的数,即等差数列的末项 接着随机取一些数组中的数,对他们两两做差,把得到的差取gcd即为公差 例a={1,5,9,13},我们随机取了1 9 ...

  2. 随机算法 - Miller_Rabin pollard_rho

    #include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #in ...

  3. 微信红包中使用的技术:AA收款+随机算法

    除夕夜你领到红包了吗?有的说“我领了好几K!”“我领了几W!” 土豪何其多,苦逼也不少!有的说“我出来工作了,没压岁钱了,还要发红包”.那您有去抢微信红包吗?微信群中抢“新年红包”春节爆红.618微信 ...

  4. POJ 3318 Matrix Multiplication(随机算法)

    题目链接 随机算法使劲水...srand((unsigned)time(0))比srand(NULL)靠谱很多,可能是更加随机. #include <cstdio> #include &l ...

  5. 抽奖随机算法的技术探讨与C#实现

    一.模拟客户需求 1.1 客户A需求:要求每次都按照下图的概率随机,数量不限,每个用户只能抽一次,抽奖结果的分布与抽奖概率近似. 1.2 客户B需求:固定奖项10个,抽奖次数不限,每个用户只能抽一次, ...

  6. hdu 4712 (随机算法)

    第一次听说随机算法,在给的n组数据间随机取两个组比较,当随机次数达到一定量时,答案就出来了. #include<stdio.h> #include<stdlib.h> #inc ...

  7. 权重随机算法的java实现

    一.概述 平时,经常会遇到权重随机算法,从不同权重的N个元素中随机选择一个,并使得总体选择结果是按照权重分布的.如广告投放.负载均衡等. 如有4个元素A.B.C.D,权重分别为1.2.3.4,随机结果 ...

  8. hdu 4712 Hamming Distance ( 随机算法混过了 )

    Hamming Distance Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

  9. HDU4712+随机算法

    随机算法 求n个20位的2进制串的MinDist. Dist:两个串的异或结果中1的个数 /* 随机算法 */ #include<algorithm> #include<iostre ...

随机推荐

  1. vue.js(14)--自定义全局指令

    <input type="text" class="form-control" v-model="keywords" v-focus& ...

  2. css:鼠标点击出现有颜色的边框?如何解决

    今天遇到上图这样出现有颜色的边框 解决办法: css设置属性 outline:none;

  3. Ubuntu NFS搭建过程

    先简单介绍一下NFS服务器是什么? NFS server可以看作是一个FILE SERVER,它可以让你的PC通过网络将远端的NFS SERVER共享出来的档案MOUNT到自己的系统中,在CLIENT ...

  4. $2019$各种$WC$没去记

    \(2019\)各种\(WC\)没去记 太弱了去不了啊. 至少我联赛没退役是吧...(退役感++ 不过这个分数线还是有点让人自闭啊,划线人绝对有毒,有人关照一下空巢老人\(mona\)喵? 这里大概是 ...

  5. django之csrf_exempt解决跨域请求的问题

    一: from django.views.decorators.csrf import csrf_exempt # 获取微信返回的code信息 @csrf_exempt def wechat_auth ...

  6. Git常用命令的操作

    Git命令 一.创建版本库 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 使用命令git add <file>,注意,可反复多次使用,添加多个文件: 使 ...

  7. 一些vue 响应式系统的底层的细节

    当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/ ...

  8. 【2019 Multi-University Training Contest 8】

    01: 02: 03:https://www.cnblogs.com/myx12345/p/11655876.html 04: 05: 06:https://www.cnblogs.com/myx12 ...

  9. log4j file 路径

    默认以System.getProperty("user.dir")为准 用LOGGER.warn(System.getProperty("user.dir")) ...

  10. FCC 成都社区·前端周刊 第 10 期

    1. Node.js 10 正式发布 在过去的一周,Node.js 10.0.0 正式发布,带来大量改进和修复.这是自 Node.js Foundation 开展以来的第七个主要版本,并将在 2018 ...