题干:

You are given a sequence a consisting of n integers. Find the maximum possible value of  (integer remainder of ai divided by aj), where 1 ≤ i, j ≤ n and ai ≥ aj.

Input

The first line contains integer n — the length of the sequence (1 ≤ n ≤ 2·105).

The second line contains n space-separated integers ai (1 ≤ ai ≤ 106).

Output

Print the answer to the problem.

Examples

Input

3
3 4 5

Output

2

解题报告:

拿到题,涉及取模操作,要知道可肯定和因子有关,因为a%m我可以认为是模掉了(a减去了)一个m,两个m,三个m。。等等。这题就是利用这个原理,我们先把他离散化到数组中,然后枚举1~1e6(相当于去重了),如果当前数字出现过,那就枚举他的倍数。。。所以我们需要预处理一个bk数组,使得对于x,可以O(1)求出小于x的最大的数字。要记得处理数组的时候需要处理到2 * 1e6。因为你枚举是刚开始就 i + i 了,细节要注意。

实际思考的思路实际是这样:

然后考虑对于Ai来讲,其能够找到的Aj如果是Ai的因子,那么一定Ai%Aj==0.如果此时Aj是Ai的最大因子数(不包括Ai本身),那么A[ i ]%A[ j + 1 --->i-1]是会逐渐递减的,所以那么我们每一次找到一个因子数,那么期望的最大模值肯定要在A[ i ]%A[ j + 1 ]中选取,所以我们可以考虑O(n)枚举Ai然后sqrt(A[i])去枚举因子数,然后过程维护一个最大值即可。总时间复杂度O(n*sqrt(n)).

我们刚刚是在枚举因子数,所以还要话sqrt(n)的时间去算因子,反过来想,我们不妨枚举倍数。那么我们需要枚举1e6+1e6/2+1e6/3+1e6/4+.............1e6/1e6次,也就是logn的时间复杂度。(也就是 对于a%m,刚开始我们是枚举a然后找对应的m,再把m改大一点点,维护最大值。现在变成a%m去枚举m,然后找对应的a,再把a改小一点点,维护最大值。)

那么我们枚举一个数之后,枚举其倍数,对应在数组中找到比这个倍数小的最大的数,那么ans=max(ans,这个倍数小的最大的数%枚举出来的这个数);

实现方式可以二分,这样复杂度多一个log,我们也可以先预处理出来答案然后O(1)查询,详情见代码。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e6 + 5;
ll a[MAX],ans,maxx;
int bk[MAX];
const ll INF = 0x3f3f3f3f3f;
int main() {memset(bk,-1,sizeof bk);int n;cin>>n;for(int i = 1; i<=n; i++) scanf("%lld",a+i) , bk[a[i]] = a[i] , maxx = max(maxx,a[i]);sort(a+1,a+n+1);for(int i = 1; i<=2000050; i++) {if(bk[i] == -1) bk[i] = bk[i-1];}for(int i = 1; i<=1000050; i++) {if(bk[i] != i) continue;for(int j = 2*i; j<=2000050; j+=i) {if(bk[j-1] > i) ans = max(ans,1ll*bk[j-1]%i);}}printf("%lld\n",ans);return 0;
}

AC代码2:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e6 + 5;
ll a[MAX],ans,maxx;
int bk[MAX];
const ll INF = 0x3f3f3f3f3f;
int main() {memset(bk,-1,sizeof bk);int n;cin>>n;for(int i = 1; i<=n; i++) scanf("%lld",a+i) , bk[a[i]] = a[i] , maxx = max(maxx,a[i]);sort(a+1,a+n+1);for(int i = 1; i<=1000050; i++) {if(bk[i] == -1) bk[i] = bk[i-1];}for(int i = 1; i<=1000050; i++) {if(bk[i] != i) continue;for(int j = i; j<=1000050; j+=i) {if(bk[j-1] > i) ans = max(ans,1ll*bk[j-1]%i);if (bk[1000050] > i) {ans = max(ans, 1ll*bk[1000050] % i);}}}printf("%lld\n",ans);return 0;
}
/*
2
1000000 999999
*/

TLE代码:

 for(int i = 1; i<=n; i++) {for(int j = 2*a[i]; j<=2000050; j+=a[i]) {if(bk[j-1] > a[i]) ans = max(ans,bk[j-1]%a[i]);}}

不能这么写,,,如果是2e5个1,分分钟给你卡成n*2.。(当然你先去重就另说了)

所以看一个题,不能直接看数据范围算复杂度,还需要看实际实现代码的姿势的最差复杂度,或者是否有特殊样例可以卡T,避免被卡。

【CodeForces - 485D】Maximum Value (枚举,用数组离散化,数学,取模运算,因子,筛法)相关推荐

  1. kattis ones简单题取模运算+枚举

    题目链接原链接 题目 给定不被2和5整除的整数n,有些n的倍数是十进制中的1的序列(比如111,1111111).其中最小的一个1的序列是几位数字? 比如数字3的37倍是111.所以是三位 Given ...

  2. Codeforces 484B Maximum Value(高效+二分)

    题目链接:Codeforces 484B Maximum Value 题目大意:给定一个序列,找到连个数ai和aj,ai%aj尽量大,而且ai≥aj 解题思路:类似于素数筛选法的方式,每次枚举aj,然 ...

  3. 【CodeForces 332B --- Maximum Absurdity】递推

    [CodeForces 332B --- Maximum Absurdity]递推 题目来源:点击进入[CodeForces 332B - Maximum Absurdity] Description ...

  4. [CodeForces 332B]Maximum Absurdity[DP]

    题目链接: [CodeForces 332B]Maximum Absurdity[DP] 题意分析: 寻找两个不重叠的长度为k的子串,使得它们之和最大. 解题思路: 第一想法是,处理出从这个点开始,长 ...

  5. POJ - 3693 Maximum repetition substring(后缀数组+RMQ)

    题目链接:点击查看 题目大意:给出一个字符串,求出字符串中 重复次数最多的连续重复子串 ,如果有多个答案,输出字典序最小的 题目分析:又是一个模板题,这里放一个大佬的博客,讲的很清楚: https:/ ...

  6. 数组和枚举、数组、二维数组、指针

    1.枚举和数组可以结合: enum StudentNames{ KENNY, // 0 KYLE, // 1 STAN, // 2 BUTTERS, // 3 CARTMAN, // 4 MAX_ST ...

  7. Codeforces B. Dubious Cyrpto (枚举 / 模拟) (Round #657 Div.2)

    传送门 题意: 已知存在三个数a,b,c满足l <= a,b,c <= r,且m = n * a + b - c.现在告诉你l,r和m的值,需要你找到一组可行的a,b,c. 思路: 枚举a ...

  8. Codeforces Round #104 (Div. 2) E DP(01背包模型) +组和+除法取模求逆元

    题意: 规定只包含4或7的数为幸运数字,给定n个数的序列,求他的子序列,使得该子序列的长度为k并且满足该子序列中不存在相同的两个幸运数字.问一共寻在多少种可能.(只要该数的下标不同则认为是不同的序列) ...

  9. PHP遇到json解决的两个办法,转为数组,直接取值

    为什么80%的码农都做不了架构师?>>>    PHP遇到json解决的两个办法,转为数组,直接取值 //转为Array数据 $json = '{"a":1,&q ...

最新文章

  1. 软件测试开发:常见测试类型概念
  2. java多线程编程01---------基本概念
  3. androd之绘制文本(FontMetrics)
  4. MySQL通配符代替引号,MySQL通配符替换
  5. Python+tkinter实现简单的登录界面
  6. 服务器压力测试实现步骤,测试web性能时 做一个压力测试的四大步骤
  7. java代码注释规范
  8. php获取 微信unionid,微信授权登录获取openId和unionId
  9. MOSEK优化包的安装、使用及注册:以Matlab中的二次规划为例
  10. python syntax error_python提示Syntax Error报错解决教程
  11. 概率论得学习整理--番外3:二项式定理和 二项式系数
  12. 娃哈哈的困境,宗庆后的难题
  13. 多关卡连连看php源码_【Ctrl.js】快手小游戏-连连看源码
  14. mysql创建表里主码和外码_SQL语言创建表时候怎么定义主码和外码
  15. Windows 计算机上查看 DNS 缓存的方法
  16. dpi和css,DPI和像素、厘米、英寸之间的关系和换算及CSS中的长度单位、位深度、ppi...
  17. RSA加密算法讲解及C++实现
  18. spring Cloud与它的好兄弟分布式
  19. python中import上级文件夹
  20. python编程计算圆面积math_python编程计算圆面积

热门文章

  1. 主题:的中间层框架 第一节
  2. 第五课 机器学习中的特征工程
  3. [Leetcode][第130题][JAVA][被围绕的区域][DFS][BFS]
  4. 【模板】在build中配置resources来防止我们资源导出失败的问题
  5. sql如何遍历几百万的表_SQL Server遍历表中记录的2种方法(使用表变量和游标)
  6. eclipse xml文件报错_Maven教程6: Maven与Eclipse整合
  7. python可以测试java的代码吗_使用python做你自己的自动化测试--对Java代码做单元测试 (2)-导入第三方jar包裹...
  8. python控制语句实验报告,python流程控制语句案例练习
  9. python获取mac窗口程序内容_在Mac OS X中获取当前活动窗口/文档的标题
  10. ubuntu安装python_ubuntu18.04下源码编译安装最新版本Python3