专栏文章
CF484B
CF484B题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miomps7n
- 此快照首次捕获于
- 2025/12/02 21:43 3 个月前
- 此快照最后确认于
- 2025/12/02 21:43 3 个月前
题面
一个数组,求数组中大数模小数的最大值。
题解
你好。重复的元素没有用,而且由于只需要满足 ,所以可以直接排序并去重。
第一个暴力就是直接从小到大排序并去重,然后枚举 ,时间复杂度 。
然后发现这里的 有一些特殊的数据性质,它只开到了 ,于是可以打出第二个暴力。
排序去重后,枚举 ,并从大到小枚举它的模数 判断 是不是可行的解,我开了个桶存 表示 在不在数组 中,然后由 往上跳,如果遇到 ,则此时 唯一个合法的解。
然后发现不管怎么剪枝复杂度还是过不了,那考虑再次优化算法。
把枚举 优化,对于每个 ,由 向上跳。找在 中离 最近的数字。
还记得 吗?开一个数组 , 存最大的 使得 ( 中离 最近的数)。所以对于每个 有 ,接着做一下前缀处理就行了。
最后只需要求 ,并且判断一下它是否在区间 中即可。
令 为 的最大值,排序去重后往上跳的时间开销为 ,不超过调和级数 。
代码
CPP#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+15;
int n;
int a[N],s[N*10],m;
int ans;
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]),m=max(a[i],m);
sort(a+1,a+1+n);
n=unique(a+1,a+1+n)-a-1;
for(int i=1;i<=n;i++) s[a[i]]=a[i];
for(int i=1;i<=2*m;i++) if(!s[i]) s[i]=s[i-1];
for(int i=1;i<n;i++) {
for(int j=2*a[i];j<=m+a[i];j+=a[i]) {
if(s[j-1]>j-a[i]) ans=max(ans,s[j-1]%a[i]);
}
}
printf("%d",ans);
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...