51nod 1421 最大MOD值 codeforce 484B. Maximum Value【調和級數複雜度T_T】
阿新 • • 發佈:2018-11-24
文章目錄
題目連結:
參考部落格:https://blog.csdn.net/linkfqy/article/details/78300976
對哈,裡面那層迴圈的複雜度是調和級數,數越大列舉這個數的倍數就越小
然後就是找一段範圍內最大的數,最開始竟然沒有反應過來,就是找這段範圍的最右邊看在哪裡,他的左邊一個不就是這段範圍裡最大的嘛~
#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int maxn= 2e5+5;
int a[maxn];
int main()
{
int N;
while(cin>>N)
{
int ans=0;
for(int i=1;i<=N;i++)scanf("%d",a+i);
sort(a+1,a+1+N);
for(int i=1;i<=N;i++)
{
if(a[i]==a[i-1])continue;//只要第一個來判斷
for(int k=2;k*a[i]<=a[N];k++)
{
int pos=lower_bound(a+1,a+1+N,k*a[i])-a;
ans= max(ans,a[pos-1]%a[i]);//找到a[pos]這個數,再往前面一個數a[pos-1]肯定在[k*ai,(k+1)*ai]範圍內
}
ans=max(ans,a[N]%a[i]);//剩下不夠倍數的一段,最後的是最大的
}
cout<<ans<<endl;
}
}
然後就是因為 的資料範圍是1e6,所以闊以用個數組b[i]來儲存小於 i 的最大的a[]陣列中的數是多少,這樣中間那層二分就變成 的了。用這種方法只跑了109ms,而上面二分那個跑路608ms,優化很明顯呀~
#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int maxn=2e5+5;
int a[maxn],b[maxn*5];//b[i]表示a[]陣列中比i小的最大的數
int main()
{
int N;
while(cin>>N)
{
int ans=0;
for(int i=1;i<=N;i++)scanf("%d",a+i);
sort(a+1,a+1+N);
N=unique(a+1,a+1+N)-(a+1);
for(int i=1,j=0;i<=1000000;)
{
if(i>a[j]&&i<=a[j+1])b[i++]=a[j];
else if(j==N)b[i++]=a[N];
else j++;
}
for(int i=1;i<=N;i++)
{
for(int k=2;k*a[i]<=a[N];k++)
{
ans=max(ans,b[k*a[i]]%a[i]);
}
ans=max(ans,a[N]%a[i]);//剩下不夠倍數的一段,最後的是最大的
}
cout<<ans<<endl;
}
}