有一个a数组,里面有n个整数。现在要从中找到两个数字(可以是同一个) ai,aj ,使得 ai mod aj 最大并且 ai ≥ aj。

Input
单组测试数据。
第一行包含一个整数n,表示数组a的大小。(1 ≤ n ≤ 2*10^5)
第二行有n个用空格分开的整数ai (1 ≤ ai ≤ 10^6)。
Output
输出一个整数代表最大的mod值。
Input示例
3
3 4 5
Output示例
2

题解:首先考虑mod的真正定义
a%b=a/b*b+c
思考一下其实是kb+c的形式,画在数轴上就是

很显然,如果有一个数x%a>b%a他肯定会在(k*a+b,(k+1)*a)的区间之中,到底有没有这些数存在可以用前缀和O(1)查询

所以因此我们就可以对c即余数进行二分了,不过二分的时候检验是O(nlogn)的,因为会枚举每一个数的倍数的区间,总复杂度大约是调和级数即logn 但其实仔细一想这是不满的

在套上二分,复杂度是O(nlognlogn) 

代码如下:

#pragma GCC optimize("inline",3)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; int vis[],sum[],k,n,a[],cnt; int check(int x)
{
for(register int i=;i<=cnt;++i)
{
for(register int j=a[i];j<=1e6;j+=a[i])
{
if(sum[j+a[i]-]-sum[j+x-]>)
{
return ;
}
}
}
return ;
} int main()
{
scanf("%d",&n);
int tmp;
for(register int i=;i<=n;++i)
{
scanf("%d",&tmp);
if(!vis[tmp])
{
vis[tmp]=;
}
}
for(register int i=;i<=2e6;++i)
{
sum[i]=sum[i-]+vis[i];
}
for(int i=;i<=1e6;i++)
{
if(vis[i])
{
a[++cnt]=i;
}
}
register int l=,r=2e6,mid;
while(l<r)
{
int mid=(l+r)>>;
if(check(mid))
{
l=mid;
}
else
{
r=mid-;
}
if(r-l<=)
{
r=check(r)?r:l;
break;
}
}
printf("%d\n",r);
}

这个程序1e5跑跑是非常轻松的但是到了2e5就有点力不从心了

直接提交到51nod上就大概只能过18个点

于是考虑优化,其实只要知道了上面那个mod的定义,我们每次对于(k+1)*ai找到小于它的最大aj,那么这个aj%ai的值肯定是(k*ai,(k+1)*ai)区间内所有数%ai最大的

因此我们可以先预处理出f[i]为比i小的最大ai,然后在向上面一样枚举区间对于每个区间计算最大模数更新答案,因为省去了二分,复杂度就是O(nlogn)

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; int b[],a[],n,t,ans=-; int cmp(int a,int b)
{
return a>b;
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+,a+n+,cmp);
int t=unique(a+,a+n+)-a-;
n=t;
int j=; for(int i=2e6;i>=;i--)
{
while(j<=n&&a[j]>=i) j++;
b[i]=a[j];
}
for(int i=;i<=n;i++)
{
for(int j=;j<=2e6/a[i];j++)
{
ans=max(ans,b[a[i]*j]%a[i]);
}
}
printf("%d\n",ans);
}
 

yzy大佬用set随手A掉了此题
详见这里
https://blog.csdn.net/yzyyylx/article/details/81013038

51nod 1421 最大MOD值(高妙的调和级数复杂度)的更多相关文章

  1. 51nod 1421 最大MOD值 | 暴力

    题面 有一个a数组,里面有n个整数.现在要从中找到两个数字(可以是同一个) ai,aj ,使得 ai mod aj 最大并且 ai ≥ aj. Input 单组测试数据. 第一行包含一个整数n,表示数 ...

  2. 51 nod 1421 最大MOD值

    1421 最大MOD值 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个a数组,里面有n个整数.现在要从中找到两个数字(可以 ...

  3. 1421 最大MOD值

    1421 最大MOD值 基准时间限制:1 秒 空间限制:131072 KB  有一个a数组,里面有n个整数.现在要从中找到两个数字(可以是同一个) ai,aj ,使得 ai mod aj 最大并且 a ...

  4. 51nod 1421:最大MOD值

    1421 最大MOD值 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个a数组,里面有n个整数.现在要从中找到两个数字(可以 ...

  5. 51nod1421 最大MOD值

    O(n2)tle.O(nlognlogn) #include<cstdio> #include<cstring> #include<cctype> #include ...

  6. 51Nod 1421

    1421 最大MOD值 有一个a数组,里面有n个整数.现在要从中找到两个数字(可以是同一个) ai,aj ,使得 ai mod aj 最大并且 ai ≥ aj. Input 单组测试数据. 第一行包含 ...

  7. 51Nod 1004 n^n的末位数字(日常复习快速幂,莫名的有毒,卡mod值)

    1004 n^n的末位数字 题目来源: Author Ignatius.L (Hdu 1061) 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给出一个整数N,输出 ...

  8. 关于程序设计中经常出现的INF和MOD值的设定

    摘自:https://www.cnblogs.com/gfvod/p/5548313.html 在取模操作中,我们常把MOD设置为1000000007,模一个大数和模一个质数可以减少冲突,而1e9+7 ...

  9. 关于程序设计中INF和MOD值的设定

    在取模操作中,我们常把MOD设置为1000000007 模一个大数和模一个质数可以减少冲突 而1e9+7又有一个很好的特点,就是相加不会爆int,相乘不会爆long long 在设置无穷大值时中我们常 ...

随机推荐

  1. FreeRADIUS 、DaloRADIUS 搭建记录

    一.  安装环境 系统环境:centos6.5 IP:192.168.30.242 hostname:vpn.org 软件:PPTP.LAMP均已安装.(请确保这些正常安装,并能使用). 二.  软件 ...

  2. OD 实验(二) - 绕过序列号验证

    需要破解的程序 输入用户名和序列号,点击 Check,程序会进行校验 用 OD 打开程序 按快捷键 Ctrl+F9 跟随表达式 GetDlgItemTextA 点击 ok 在这里调用了 GetDlgI ...

  3. 【合】C#线程

    浅谈ThreadPool 线程池 地址:https://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html 相关概念: 线程池可以看做容纳线程 ...

  4. 函数~匿名方法~lambda的逐渐过渡思想

    前提:基于委托实现 (1)使用函数名称 delegate void Printer(string s);//(1)申明委托 static void Main(string[] args) { //(3 ...

  5. 什么是事件代理?DOM2.0标准事件模型的三个阶段

    体验更优排版请移步原文:http://blog.kwin.wang/programming/js-event-delegation.html 事件代理,又称事件委托(Delegation),就是将处理 ...

  6. 汉字转拼音开源工具包Jpinyin介绍

    最近要实现一个根据词语得到词语对应拼音的功能,找到了Jpinyin这个开源工具包,使用下来发现它非常强大,完全满足我的需求,下面对它做一个简单的介绍,希望能够帮助到有需要的朋友. https://gi ...

  7. StringUtils.hasText()

    StringUtils.hasText(字符串) 如果字符串里面的值为null, "", "   ",那么返回值为false:否则为true

  8. bash's [ command & [[ keyword

    [bash's [ command & [[ keyword] [ (test) command: bash中的条件测试語句, [ condition ], 并不是一个語句, 而是一个命令, ...

  9. Excel VBA入门(三) 流程控制1-条件选择

    VBA中的流程控制分为两种,其一是条件结构式的,即根据条件判断的结果去选择性执行相应的语句(块):另一种是循环,即循环地执行语句(块).本节介绍第一种. 1. IF if 语句其实包含有几种形式: ① ...

  10. go_指针

    值传递:相当于在内存中拷贝一分变量出来,拷贝变量的改变对原变量不影响 引用传递:直接引用内存中的变量,会被改变 c,c++值传递和引用传递都有 Java,python多用引用传递 go语言指针简单之处 ...