正题
题目大意
nnn个数,求一对(i,j)(i,j)(i,j)要求最大化max{ai,aj}%min{ai,aj}max\{a_i,a_j\}\% min\{a_i,a_j\}max{ai,aj}%min{ai,aj}
解题思路
我们考虑枚举小的那一个iii,显然在ki∼k(i+1)−1ki\sim k(i+1)-1ki∼k(i+1)−1这段范围都是要减去一个kikiki。RMQRMQRMQ查询最大值即可。
时间复杂度O(nlogn)O(n\log n)O(nlogn)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
const int N=1e6;
int read() {int x=0,f=1; char c=getchar();while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();return x*f;
}
int n,ans,lg[N+10],f[N+10][21];
int get_min(int l,int r){if(r>N)r=N;int z=lg[r-l+1];return max(f[l][z],f[r-(1<<z)+1][z]);
}
int main()
{
// freopen("data.txt","r",stdin);n=read();for(int i=2;i<=N;i++)lg[i]=lg[i>>1]+1;for(int i=1;i<=n;i++){int x=read();f[x][0]=x;}for(int j=1;j<=20;j++)for(int i=1;i+(1<<j)-1<=N;i++)f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);for(int i=1;i<=N;i++)if(f[i][0]){for(int j=i;j<=N;j+=i)ans=max(ans,get_min(j,j+i-1)-j);}printf("%d",ans);
}