题目链接:hdu 4961
bi表示第i位左边最靠右的ai的倍数,ci表示第i位右边最靠左的ai的倍数求bi*ci的和
开一个vector,p[i]记录i的倍数的所有位置,然后从前向后扫一边找出每个数倍数左边以及右边的数即可
/******************************************************
* File Name: 1002.cpp
* Author: kojimai
* Creater Time:2014年08月19日 星期二 13时22分49秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
#define FFF 100005
long long a[FFF];
vector<int> p[100005];
int qfind(int x)
{
int l=0,r=p[a[x]].size()-1,mid;
while(l<=r)
{
mid=(l+r)/2;
if(p[a[x]][mid]==x)
return mid;
else if(p[a[x]][mid]<x)
l=mid+1;
else
r=mid-1;
}
}
int main()
{
int n;
while(scanf("%d",&n),n)
{
for(int i=1;i<100005;i++)
p[i].clear();
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
p[a[i]].push_back(i);
for(int j=2;j*j<=a[i];j++)
{
if(a[i]%j==0)
{
p[j].push_back(i);
if(j*j!=a[i])
p[a[i]/j].push_back(i);
}
}
}
long long ans=0;
for(int i=1;i<=n;i++)
{
int l,r;
if(a[i]==1)
{
if(i==1)
l=1;
else
l=i-1;
if(i==n)
r=i;
else
r=i+1;
}
else
{
int x=qfind(i);
if(x==0)
l=i;
else
l=p[a[i]][x-1];
if(x==p[a[i]].size()-1)
r=i;
else
r=p[a[i]][x+1];
}
ans+=a[l]*a[r];
}
cout<<ans<<endl;
}
return 0;
}