hdu 4961 Boring Sum(高效)

题目链接:hdu 4961 Boring Sum

题目大意:给定ai数组;

  • 构造bik=max(j|0<j<i,aj%ai=0)bi=ak;
  • 构造cik=min(j|i<jn,aj%ai=0)ci=ak;
    i=1nbici

解题思路:由于ai105,所以预先处理好每一个数的因子,然后在处理bici数组的时候,每次遍历一个数。就将其全部的因子更新,对于bi维护最大值,对于ci维护最小值。

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;
typedef long long ll;
const int maxn = 1e5;
const int INF = 0x3f3f3f3f;

int n, arr[maxn+5], b[maxn+5], c[maxn+5], v[maxn+5];
vector<int> g[maxn+5];

void get_factor (int n) {
    for (int i = 1; i <= n; i++)
        g[i].clear();

    for (int i = 1; i <= n; i++) {
        for (int j = i; j <= n; j += i)
            g[j].push_back(i);
    }
}

void init () {

    memset(v, 0, sizeof(v));
    for (int i = 1; i <= n; i++) {
        int u = arr[i];
        int k = (v[u] == 0 ? i :v[u]);
        b[i] = arr[k];

        for (int j = 0; j < g[u].size(); j++)
            v[g[u][j]] = max(v[g[u][j]], i);
    }

    memset(v, INF, sizeof(v));
    for (int i = n; i >= 1; i--) {
        int u = arr[i];
        int k = (v[u] == INF ? i : v[u]);
        c[i] = arr[k];

        for (int j = 0; j < g[u].size(); j++)
            v[g[u][j]] = min(v[g[u][j]], i);
    }
}

int main () {
    get_factor(maxn);

    while (scanf("%d", &n) == 1 && n) {
        for (int i = 1; i <= n; i++)
            scanf("%d", &arr[i]);
        init();

        ll ans = 0;
        for (int i = 1; i <= n; i++)
            ans = ans + b[i] * 1LL * c[i];
        printf("%I64d\n", ans);
    }
    return 0;
}
posted @ 2017-04-15 20:43  lytwajue  阅读(130)  评论(0编辑  收藏  举报