題解 CF484B 【Maximum Value】
阿新 • • 發佈:2020-09-11
題解
我們考慮在值域上做,設值域為 \(m\) 。
我們可以考慮數論分塊,對於一對 \(a_i\) 和 \(a_j\) ,$\left \lfloor \frac{a_i}{a_j} \right \rfloor $ 的取值只有 \(\sqrt{a_i}\) 個,所以我們考慮在相同的取值中取最小的 \(a_j\) 進行更新答案,就可以得到 \(a_i \bmod a_j\) 的最大值。
由於是在值域上做數論分塊同時還要維護區間最值,複雜度為 \(O(n\sqrt m~log~m )\) 過不了……
考慮進行優化,我們可以發現這個區間最值是在值域上搞的,可 \(O(m)\) 預處理,然後複雜度降為 \(O(n\sqrt 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\n",ans); return 0; }