首先,进行一个翻译
有一个0到n-1的数轴,数轴上每个点有一个权重si。一只青蛙从0开始,要往前跳A(A>0),再往后跳B(B>0),不能跳到重复的点上,一直循环这两个动作直到跳到n-1。然后把青蛙跳过的点上的权重si相加,记作ans,选最优的A,B,算出对应的最大的ans。
那么很显然,我们会发现把青蛙的路径反过来,也就是从n-1跳到0,和正着跳没什么区别,也就是说青蛙跳过的点是左右对称的,而且显然A>B,如果记C=A-B>0(A!=n-1)青蛙必然跳过(C,2C,3C,……,kC)由于对称性,就也跳过(n-1-C,n-1-2C,n-1-3C,……n-1-kC)。
那么我们枚举C,k。算最大值就可以。下面的指针i对应C,j对应k。
但是要注意,有一个隐藏条件,就是青蛙跳到kC的时候,下一步往前跳A,不能跳出n-1,也就是
if(n-1-i*j-i<=0) break;
如果n-1-i*j<=0,即(k+1)C>=n-1,那么由于C<A,则kC+A>n-1,而且可以让B取到1,反过来推也成立,也就是n-1-i*j<=0等价kC+A>n-1。
#pragma GCC optimize(3)
#include<stdio.h>
#define N 100010
typedef long long i64;
int s[N],check[N];
i64 max(i64 a,i64 b){
return a>b?a:b;
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&s[i]);
}
i64 ans=0,res=0;
for(int i=1;i<n-1;i++){
res=0;
for(int j=1;i*j<n-1;j++){
if(n-1-i*j-i<=0) break;
if(check[i*j]==i||check[n-1-i*j]==i||i*j==n-1-i*j) break;
check[i*j]=i,check[n-1-i*j]=i;
res+=(i64)s[i*j]+(i64)s[n-1-i*j];
ans=max(res,ans);
}
}
printf("%lld\n",ans);
return 0;
}