题目链接:HDU - 6098
我们枚举每个数字,然后找到他的倍数,这个过程是一个调和级数,所以我们只需要知道每个区间的max即可。
用ST表预处理。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,a[N],f[N][20];
inline int ask(int l,int r){int k=log2(r-l+1); return max(f[l][k],f[r-(1<<k)+1][k]);}
inline void solve(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),f[i][0]=a[i];
for(int j=1;j<=17;j++) for(int i=1;i<=n-(1<<j)+1;i++)
f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
for(int i=2,res;i<=n;i++){
res=ask(1,i-1);
for(int j=i;j<n;j+=i) res=max(res,ask(j+1,min(n,j+i-1)));
printf("%d%c",res,i==n?'\n':' ');
}
}
signed main(){
int T; cin>>T; while(T--) solve();
return 0;
}