题目链接:http://codeforces.com/problemset/problem/1154/G

题目大意:

  给定n个数,在这些数中选2个数,使这两个数的最小公倍数最小,输出这两个数的下标(如果有多组解,任意输出一组即可)。

分析:

  直接2个循环两两配对一下肯定要超时的,这里可以考虑枚举公因数,因为LCM是与最大公因数相关的,如果我们枚举了所有的公因数,那么我们就枚举了所有的LCM。

  对于每一个公因数d,含有因子d的数从小到大排序为x1,x2,x3……xn,共有n个。

  首先计算一下前两个数的GCD,有2种可能:

  1:如果GCD(x1,x2) == d,那就没必要再计算GCD(xi,xj) (1 < i < j <= n)了,只要计算一下LCM(x1,x2)即可,因为如果GCD(xi,xj) == d,LCM(xi,xj)肯定大于LCM(x1,x2);如果GCD(xi,xj) == d_ > d,LCM(xi,xj)有可能小于LCM(x1,x2),不过这个等d枚举到了d_再算也是一样的。

  2:如果GCD(x1,x2) == d_ > d,没必要再计算LCM(x1,x2),可以等到枚举到d_再计算,也没必要再计算GCD(xi,xj),因为如果GCD(xi,xj) == d,LCM(xi,xj) = xi * xj / d > x1 * x2 / d > x1 * x2 / d_ = LCM(x1,x2);如果GCD(xi,xj) > d,也不需要。

代码如下:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define Rep(i, n) for (int i = 0; i < (n); ++i)
  5. #define rRep(i, n) for (int i = (n) - 1; i >= 0; --i)
  6. #define For(i, s, t) for (int i = (s); i <= (t); ++i)
  7. #define rFor(i, t, s) for (int i = (t); i >= (s); --i)
  8. #define foreach(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
  9. #define rforeach(i, c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
  10.  
  11. #define INIT() std::ios::sync_with_stdio(false);std::cin.tie(0);
  12. #define pr(x) cout << #x << " = " << x << " "
  13. #define prln(x) cout << #x << " = " << x << endl
  14. #define EL() printf("\n")
  15. #define GL(s) getline(cin, (s))
  16. #define SHOW_VECTOR(v) {std::cerr << #v << "\t:"; for(const auto& xxx : v){std::cerr << xxx << " ";} std::cerr << "\n";}
  17. #define SHOW_MAP(v) {std::cerr << #v << endl; for(const auto& xxx: v){std::cerr << xxx.first << " " << xxx.second << "\n";}}
  18.  
  19. template<typename T1, typename T2>
  20. istream &operator>>(istream &in, pair<T1, T2> &p) {
  21. in >> p.first >> p.second;
  22. return in;
  23. }
  24.  
  25. template<typename T>
  26. istream &operator>>(istream &in, vector<T> &v) {
  27. for (auto &x: v)
  28. in >> x;
  29. return in;
  30. }
  31.  
  32. template<typename T1, typename T2>
  33. ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
  34. out << "[" << p.first << ", " << p.second << "]" << "\n";
  35. return out;
  36. }
  37.  
  38. #define LOWBIT(x) ((x)&(-x))
  39.  
  40. #define ALL(x) x.begin(),x.end()
  41.  
  42. #define ms0(a) memset(a,0,sizeof(a))
  43. #define msI(a) memset(a,inf,sizeof(a))
  44. #define msM(a) memset(a,-1,sizeof(a))
  45.  
  46. #define MP make_pair
  47. #define PB push_back
  48. #define ft first
  49. #define sd second
  50.  
  51. inline int gc(){
  52. static const int BUF = 1e7;
  53. static char buf[BUF], *bg = buf + BUF, *ed = bg;
  54.  
  55. if(bg == ed) fread(bg = buf, , BUF, stdin);
  56. return *bg++;
  57. }
  58.  
  59. inline int ri(){
  60. int x = , f = , c = gc();
  61. for(; c<||c>; f = c=='-'?-:f, c=gc());
  62. for(; c>&&c<; x = x* + c - , c=gc());
  63. return x*f;
  64. }
  65.  
  66. typedef long long LL;
  67. typedef pair< int, int > PII;
  68. typedef pair< LL, LL > PLL;
  69. typedef map< int, int > MII;
  70. const double EPS = 1e-;
  71. const double PI = acos(-1.0);
  72. const LL mod = 1e9 + ;
  73. const LL inf = 0x7fffffff;
  74. const LL infLL = 0x7fffffffffffffffLL;
  75. const LL ONE = ;
  76. const int maxN = 1e7 + ;
  77.  
  78. struct A{
  79. int pos;
  80. int cnt = ;
  81. };
  82.  
  83. LL n, ret = infLL;
  84. A a[maxN];
  85. PLL ans;
  86.  
  87. inline LL gcd(LL x,LL y){
  88. LL t;
  89. if(!(x && y))return -;
  90. while(y){
  91. t=x%y;
  92. x=y;
  93. y=t;
  94. }
  95. return x;
  96. }
  97.  
  98. inline LL lcm(LL x,LL y){
  99. LL t = gcd(x,y);
  100. if(t == -)return -;
  101. return x/t*y;
  102. }
  103.  
  104. int main(){
  105. INIT();
  106. cin >> n;
  107. For(i, , n) {
  108. LL x;
  109. cin >> x;
  110. if(a[x].cnt == ) {
  111. a[x].pos = i;
  112. ++a[x].cnt;
  113. }
  114. else if(a[x].cnt == ) {
  115. if(x < ret) {
  116. ret = x;
  117. ans = MP(a[x].pos, i);
  118. }
  119. ++a[x].cnt;
  120. }
  121. }
  122.  
  123. // Enumerate common factor d
  124. For(d, , maxN) {
  125. LL x1 = ;
  126. for(int x2 = d; x2 < maxN; x2 += d){
  127. if(!a[x2].cnt) continue;
  128. if(!x1) x1 = x2;
  129. else{
  130. // x1,x2为前2个有公因子d的数
  131. if(gcd(x1, x2) == d){
  132. LL tmp = x2 / d * x1;
  133. if(tmp < ret){
  134. ret = tmp;
  135. ans = MP(a[x2].pos, a[x1].pos);
  136. }
  137. }
  138. break;
  139. }
  140. }
  141. }
  142.  
  143. if(ans.ft > ans.sd) swap(ans.ft, ans.sd);
  144. cout << ans.ft << " " << ans.sd;
  145. return ;
  146. }

Codeforces 1154G Minimum Possible LCM的更多相关文章

  1. Codeforces B. Minimum Possible LCM(贪心数论)

    题目描述: B. Minimum Possible LCM time limit per test 4 seconds memory limit per test 1024 megabytes inp ...

  2. Minimum Sum LCM(uva10791+和最小的LCM+推理)

    L - Minimum Sum LCM Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submi ...

  3. UVA.10791 Minimum Sum LCM (唯一分解定理)

    UVA.10791 Minimum Sum LCM (唯一分解定理) 题意分析 也是利用唯一分解定理,但是要注意,分解的时候要循环(sqrt(num+1))次,并要对最后的num结果进行判断. 代码总 ...

  4. Codeforces Round #552:G. Minimum Possible LCM

    官方题解是时间复杂度为O(nd)的.这里给出一个简单实现但是时间复杂度为O(NlogN) (N=1e7) 因为 a*b/gcd(a,b)=lcm(a,b) 所以我们可以枚举每一个因子,然后找到存在这个 ...

  5. F - Minimum Sum LCM

    LCM (Least Common Multiple) of a set of integers is defined as the minimum number, which is a multip ...

  6. UVA 10791 Minimum Sum LCM(分解质因数)

    最大公倍数的最小和 题意: 给一个数字n,范围在[1,2^23-1],这个n是一系列数字的最小公倍数,这一系列数字的个数至少为2 那么找出一个序列,使他们的和最小. 分析: 一系列数字a1,a2,a3 ...

  7. codeforces 496A. Minimum Difficulty 解题报告

    题目链接:http://codeforces.com/contest/496/problem/A 题目意思:给出有 n 个数的序列,然后通过删除除了第一个数和最后一个数的任意一个位置的数,求出删除这个 ...

  8. [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]

    这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...

  9. Minimum Sum LCM UVA - 10791(分解质因子)

    对于一个数n 设它有两个不是互质的因子a和b   即lcm(a,b) = n 且gcd为a和b的最大公约数 则n = a/gcd * b: 因为a/gcd 与 b 的最大公约数也是n 且 a/gcd ...

随机推荐

  1. WPF中应用字体图标

    一.什么是字体图标 我们在进行GDI(图形界面)编程的过程中图标是不可少的.近些年随着网络的繁荣和移动应用的繁荣,矢量图的应用越来越火. 矢量图是一种用数学方法描述的.由一系列点和线组成的图,因此相比 ...

  2. socket.setSoTimeout(1000);

    这个用来设置与socket的inputStream相关的read操作阻塞的等待时间,超过设置的时间了,假如还是阻塞状态,会抛出异常java.net.SocketTimeoutException: Re ...

  3. UVA12113-Overlapping Squares(二进制枚举)

    Problem UVA12113-Overlapping Squares Accept:116  Submit:596 Time Limit: 3000 mSec  Problem Descripti ...

  4. Raid卡介绍

    raid0条带卷 最少需要一块硬盘 可以把所有硬盘的容量都叠加在一起,可以拥有很高的读写速度,硬盘空间也能得到很好的利用 但是只要其中一块硬盘换了,数据就全丢失了 raid1镜像卷 最少需要两块硬盘, ...

  5. day2-安装python以及基本使用

    安装Python windows 1.下载安装包 https://www.python.org/downloads/ 2.安装 默认安装路径:C:\python27 3.配置环境变量 [右键计算机]- ...

  6. 在linux中查看进程占用的端口号

    在Linux 上的 /etc/services 文件可以查看到更多关于保留端口的信息. 可以使用以下六种方法查看端口信息. ss:可以用于转储套接字统计信息. netstat:可以显示打开的套接字列表 ...

  7. Linux 通过rinetd端口转发来访问内网服务

    可以通过端口映射的方式,来通过具有公网的云服务器 ECS 访问用户名下其它未购买公网带宽的内网 ECS 上的服务.端口映射的方案有很多,比如 Linux 下的 SSH Tunnel.rinetd,Wi ...

  8. python五子棋

    以后不更新了,把以前的一些东西发出来. 这是一个命令行环境的五子棋程序.使用了minimax算法. 除了百度各个棋型的打分方式,所有代码皆为本人所撸.本程序结构与之前的井字棋.黑白棋一模一样. 有一点 ...

  9. SpringBoot集成Shiro安全框架

    跟着我的步骤:先运行起来再说 Spring集成Shiro的GitHub:https://github.com/yueshutong/shiro-imooc 一:导包 <!-- Shiro安全框架 ...

  10. 吉特日化MES-日化行业原料仓库所见问题汇总

    2018年工作主要面向的是日化行业,其中包括日化生产以及日化生产原料仓库,和以往接触到仓库有点不一样在于日化行业原料的特性问题,日化行业的原料基本以粉尘和液体为主. 1. 原料的形态上: 日化行业原料 ...