题意:给出一串数列 a[1],a[2].....a[n];
所谓的b[i]是在a[i]的左边的倍数的值,c[i]是在a[i]的右边的倍数的值
若左边或右边没有倍数则是它本身
求sum=b[1]*c[1]+....b[n]*c[n];
思路:
先预处理出1-100000的约数下来。。
再用一个next数组储存这个数最近的倍数
再从左开始for 则b[i]=next[a[i]];
再更新next数组
同理得c
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
#define IN freopen ("in.txt" , "r" , stdin);
#define OUT freopen ("out.txt" , "w" , stdout);
typedef long long LL;
const int M= 100100;
vector<int>g[M];
LL next[M],b[M],c[M],a[M];
int main()
{
int n;
for(int i=1;i<=100000;i++)//得到约数
{
g[i].clear();
for(int j=1;j<=(int)sqrt(i*1.0);j++)
{
if(i%j==0)
{
g[i].push_back(j);
g[i].push_back(i/j);
}
}
}
// IN;
while(scanf("%d",&n),n)
{
memset(next,-1,sizeof(next));
for(int i=1;i<=n;i++)
scanf("%I64d",&a[i]);
for(int i=1;i<=n;i++)//得到b
{
b[i]=-1;
b[i]=max(b[i],next[a[i]]);
if(b[i]==-1)
b[i]=a[i];
for(int j=0;j<g[a[i]].size();j++)//更新next
{
next[g[a[i]][j]]=a[i];
}
}
memset(next,-1,sizeof(next));
for(int i=n;i>=1;i--)
{
c[i]=1100000;
if(next[a[i]]!=-1)
c[i]=min(c[i],next[a[i]]);
if(c[i]==1100000)
c[i]=a[i];
for(int j=0;j<g[a[i]].size();j++)
{
next[g[a[i]][j]]=a[i];
}
}
LL sum=0;
for(int i=1;i<=n;i++)
sum+=b[i]*c[i];
printf("%I64d\n",sum);
}
return 0;
}