一道数论题,

解题思路:因为ai≤10的5次方,所以预先处理好每个数的因子,然后在处理bi,ci数组的时候,每次遍历一个数,就将其所有的因子更新,对于bi维护最大值,对于ci维护最小值。

//hdu4961

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef __int64 ll;
const int MAXN = 100005;

int a[MAXN], b[MAXN], c[MAXN], vis[MAXN];
int n;
int main()
{
  while (scanf("%d", &n) && n) {
    for (int i = 1; i <= n; i++)
      scanf("%d", &a[i]);

//从前往后遍历每一个数,更新每一个数的因子,维护bi的最大值
    memset(vis, 0, sizeof(vis));
    for (int i = 1; i <= n; i++) {
      if (vis[a[i]])
        b[i] = a[vis[a[i]]];
      else
        b[i] = a[i];
      for (int j = 1; j <= (int)sqrt((double)a[i]) + 1; j++) {
        if (a[i] % j == 0) {
          vis[j] = i;
          vis[a[i] / j] = i;
        }
      }
    }

//从后往前遍历每一个数,更新每一个数的因子,维护ci的最小值

memset(vis, 0, sizeof(vis));
    for (int i = n; i >= 1; i--) {
      if (vis[a[i]])
        c[i] = a[vis[a[i]]];
      else
        c[i] = a[i];
      for (int j = 1; j <= (int)sqrt((double)a[i]) + 1; j++) {
        if (a[i] % j == 0) {
          vis[j] = i;
          vis[a[i] / j] = i;
        }
      }
    }

  ll sum = 0;
    for (int i = 1; i <= n; i++) {
      sum += (ll)b[i] * c[i];
    }
    printf("%I64d ", sum);
  }
  return 0;

}

原文地址:https://www.cnblogs.com/ACWQYYY/p/4312332.html