CF484B题解

朴素的办法是枚举每两个数然后更新取模的结果。时间复杂度为 \(O(n^2)\) 不能通过。

这个朴素的过程可以看作枚举一个数然后找对其取模最大值的过程。

我们可以枚举一个数,然后再枚举以它的倍数为两端的区间,找其中取模的最大值。
找最大值的过程可以二分或双指针。
值域很小,也可以用预处理小于某个值的最大值的方法来 \(O(1)\) 查找。

代码如下。

#include<bits/stdc++.h>
using namespace std;
constexpr int MAXN=2e5+10;
int n,a[MAXN],le[2000010],ans;
namespace sol{
    void solve(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i)scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        n=unique(a+1,a+n+1)-(a+1);
        int p=1;
        for(int i=a[1]+1;i<=2000000;++i){
            while(p<n&&a[p+1]<i)++p;
            le[i]=a[p];
        }
        for(int i=1;i<=n;++i){
            for(int j=2;(j-1)*a[i]<=a[n];++j){
                ans=max(ans,le[j*a[i]]-(j-1)*a[i]);
            }
        }
        printf("%d\n",ans);
    }
}
int main(){
    sol::solve();
    return 0;
}
posted @ 2024-02-17 11:28  LiJoQiao  阅读(12)  评论(0编辑  收藏  举报