HDU - 6098

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/107748783
hdu