CF484B Maximum Value

这个东西他一开始也是草稿

题解

我们考虑在值域上做,设值域为 (m)

我们可以考虑数论分块,对于一对 (a_i)(a_j) ,$left lfloor frac{a_i}{a_j} ight floor $ 的取值只有 (sqrt{a_i}) 个,所以我们考虑在相同的取值中取最小的 (a_j) 进行更新答案,就可以得到 (a_i mod a_j) 的最大值。

由于是在值域上做数论分块同时还要维护区间最值,复杂度为 (O(nsqrt m~log~m )) 过不了……

考虑进行优化,我们可以发现这个区间最值是在值域上搞的,可 (O(m)) 预处理,然后复杂度降为 (O(nsqrt m))

然后你再最优化剪枝就过了……

以上。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5,M=1e6+5;
int n,a[N];
int minn[M];
int ans=0;
bool cmp(int a,int b){return a>b;}
int main()
{
	cin>>n,memset(minn,63,sizeof(minn));
	for(int i=1;i<=n;++i) scanf("%d",&a[i]),minn[a[i]]=a[i];
	for(int i=1e6;i>=1;--i) minn[i]=min(minn[i],minn[i+1]);
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;++i)
	{
		for(int j=ans+1;j<=a[i];j=a[i]/(a[i]/j)+1)
		ans=max(ans,a[i]%minn[j]);
	}
	printf("%d
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/Point-King/p/13653129.html