HDU4961-Boring Sum(质因子)

点击打开链接


题意:给出n个数的数列a,bi的取值为在1 <= j < i之间如果存在aj % ai == 0,则取最大下标的值赋给bi,如果不存在,则bi = ai;ci的取值为在i < j <= n之间如果存在aj % ai == 0,则取最小下标值赋给bi,如果不存在,则ci = ai。求b1 * c1 + b2 * c2 + ... + bn * cn的和。

思路:如果直接暴力的话一定会超时,所以我们可以开一个vis数组来记录每一个值所对应的最大的下标是多少。即每查找ai,分解出ai的质因子,更新vis数组。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

typedef __int64 ll; 
//typedef long long 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]); 

        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;
                }
            }
        }

        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\n", sum); 
    }
    return 0;
}


你可能感兴趣的:(HDU4961-Boring Sum(质因子))