随机化选讲的例题

John Doe offered his sister Jane Doe find the gcd of some set of numbers a.

Gcd is a positive integer g, such that all number from the set are evenly divisible by g and there isn't such g' (g' > g), that all numbers of the set are evenly divisible by g'.

Unfortunately Jane couldn't cope with the task and John offered her to find the ghd of the same subset of numbers.

Ghd is a positive integer g, such that at least half of numbers from the set are evenly divisible by g and there isn't such g' (g' > g) that at least half of the numbers from the set are evenly divisible by g'.

Jane coped with the task for two hours. Please try it, too.

Input

The first line contains an integer n (1 ≤ n ≤ 106) showing how many numbers are in set a. The second line contains space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 1012). Please note, that given set can contain equal numbers.

Please, do not write the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the %I64d specifier.

Output

Print a single integer g — the Ghd of set a.


题目分析

随机化+复杂度分析

首先按照随机化题的处理方式,随机选一个数$a_{pos}$钦定它在答案集合内。再考虑如何找出剩下数中满足条件的最大公因数。由于这个公因数一定是$d=\gcd\{a_{pos},a_i\}$,并且所有$d|d'$的$d'$也都会算在$d$的贡献里。那么这里由复杂度分析的经验得,由于$10^{12}$内因数最多的数约有$7000$个约数,那么我们并不需要对$d$存下所有$d'$的贡献,而是每次暴力地累计答案即可。

话说为什么这个srand(time(0))的随机化正确率这么低……只有选15个数才能擦着时限过去。

 #include<bits/stdc++.h>
typedef long long ll;
const int maxn = ; int n;
ll a[maxn],ans;
std::map<ll, int> mp;
std::map<ll, int>::iterator it,tmp; ll read()
{
char ch = getchar();
ll num = ;
for (; !isdigit(ch); ch=getchar());
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num;
}
ll gcd(ll a, ll b){return !b?a:gcd(b, a%b);}
int main()
{
srand(time()), n = read();
for (int i=; i<=n; i++) a[i] = read();
for (int cse=; cse; --cse)
{
mp.clear();
int pos = 1ll*rand()*rand()%n+;
if (a[pos] <= ans) continue;
for (int i=; i<=n; i++)
{
ll val = gcd(a[pos], a[i]);
if (val > ans) ++mp[val];
}
it = mp.end();
for (int cnt; it!=mp.begin(); )
{
cnt = , --it;
if ((*it).first <= ans) break;
for (tmp=it; tmp!=mp.end(); ++tmp)
if (!((*tmp).first%(*it).first)) cnt += (*tmp).second;
if (cnt >= (n+)/) ans = (*it).first;
}
}
printf("%lld\n",ans);
return ;
}

END

最新文章

  1. (第九天)DOM事件
  2. ZooKeeper个人笔记Session管理
  3. Objective-C 再谈OC指针,对比C++/Java/Swift
  4. 1046: 最小的K个数
  5. 如何将MVC Areas中的某一个页设为起始页
  6. hdu 3498 whosyourdaddy 重复覆盖
  7. Learn Python More
  8. 【自适应辛普森积分】hdu1724 Ellipse
  9. 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.3
  10. Mesos:数据库使用的持久化卷
  11. WPF腾讯视频通话开发
  12. 完全卸载oraclean安装
  13. 亿级Web系统搭建:单机到分布式集群【转】
  14. rabbitmq系列一 之简单队列
  15. Linux启动与禁止SSH用户及IP的登录
  16. java 集合之HashMap
  17. 手脱FSG v1.33
  18. easyui 后台页面,在Tab中的链接点击后添加一个新TAB的解决方法
  19. 模拟Linux修改实际、有效和保存设置标识
  20. [Swift]在Swift中实现自增(++)、自减(--)运算符:利用extension扩展Int类

热门文章

  1. centos7.3下配置本地yum仓库
  2. Uva1608
  3. 自动化测试 - Appium + Python史上最全最简环境搭建步骤
  4. mask
  5. 机器学习框架ML.NET学习笔记【4】多元分类之手写数字识别
  6. Maven配置默认JDK/JRE版本
  7. SpringBoot | 番外:使用小技巧合集
  8. 使用Foxfly.Net读取STEP文件
  9. vs2013安装时提示核心功能错误
  10. sql server 2012不能全部用到CPU的逻辑核心数的问题