HDU - 4961 Boring Sum

Problem Description

Number theory is interesting, while this problem is boring.

Here is the problem. Given an integer sequence a1, a2, …, an, let S(i) = {j|1<=j<i, and aj is a multiple of ai}. If S(i) is not empty, let f(i) be the maximum integer in S(i); otherwise, f(i) = i. Now we
define b&#31;i as af(i). Similarly, let T(i) = {j|i<j<=n, and aj is a multiple of ai}. If T(i) is not empty, let g(i) be the minimum integer in T(i); otherwise, g(i) = i. Now we define &#31;ci as ag(i). The boring
sum of this sequence is defined as b1 * c1 + b2 * c2 + … + bn * cn.

Given an integer sequence, your task is to calculate its boring sum.

Input

The input contains multiple test cases.

Each case consists of two lines. The first line contains an integer n (1<=n<=100000). The second line contains n integers a1, a2, …, an (1<= ai<=100000).

The input is terminated by n = 0.

Output

Output the answer in a line.

Sample Input

5
1 4 2 3 9
0

Sample Output

136
题意:给你一个数组,让你生成两个新的数组,A要求每个数如果能在它的前面找个最近的一个是它倍数的数,那就变成那个数,否则是自己,C是往后找,输出交叉相乘的和
思路:扫描记录因子处理
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
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) == 1) {
		if (n == 0)
			break;
		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]+0.5); 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]+0.5); 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;
}

HDU - 4961 Boring Sum,布布扣,bubuko.com

时间: 2024-08-05 07:06:51

HDU - 4961 Boring Sum的相关文章

hdu 4961 Boring Sum(高效)

题目链接:hdu 4961 Boring Sum 题目大意:给定ai数组; 构造bi, k=max(j|0<j<i,aj%ai=0), bi=ak; 构造ci, k=min(j|i<j≤n,aj%ai=0), ci=ak; 求∑i=1nbi?ci 解题思路:因为ai≤105,所以预先处理好每个数的因子,然后在处理bi,ci数组的时候,每次遍历一个数,就将其所有的因子更新,对于bi维护最大值,对于ci维护最小值. #include <cstdio> #include <c

HDU 4961 Boring Sum 暴力

题意:对于所有的A[I],同时找到左边和右边离它最近且是它的倍数的数相乘最后加起来求和. 解题思路:n*sqrt(n)的算法,开始以为过不了,wa了两发因为lld I64d对拍一个小时发现一个小时前交的代码没错只是没变I64d,..具体思路是枚举每个a[i]的因子,找离它最近的那个更新,如果已经没更新就不用更新了.用两个辅助数组记录最近的就行. 解题代码: 1 // File Name: 1002.cpp 2 // Author: darkdream 3 // Created Time: 201

HDU 4961 Boring Sum 构造题

用一个数组c, c[i]表示i这个数出现的最近数字是几. 那么当加入一个6,则 c[1] = c[2] = c[3] = c[6] = 6; ==最近怎么都要开挂啊.. #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N = 100005; inl

HDU 4961 Boring Sum 打表、更新

点击打开链接 Boring Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 715    Accepted Submission(s): 351 Problem Description Number theory is interesting, while this problem is boring. Here is th

hdu 4961 Boring Sum(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4961 Problem Description Number theory is interesting, while this problem is boring. Here is the problem. Given an integer sequence a1, a2, -, an, let S(i) = {j|1<=j<i, and aj is a multiple of ai}. If S

hdu 4961 Boring Sum (思维 哈希 扫描)

题目链接 题意:给你一个数组,让你生成两个新的数组,A要求每个数如果能在它的前面找个最近的一个是它倍数的数,那就变成那个数,否则是自己,C是往后找,输出交叉相乘的和 分析: 这个题这种做法是O(n*sqrt(n))的复杂度,极限数据绝对会超时,但是这个题的数据有点水,所以可以过. 用vis[i]数组表示离数字 i  最近的倍数那个数在a[]中的位置,因为所有数字范围在1--100000所以可行 ,正着扫一遍,每次找到当前的数的除数,同时把除数覆盖位置,把 /除数 的数也覆盖位置. 倒着也是一样,

HDOJ 4961 Boring Sum

Discription Number theory is interesting, while this problem is boring. Here is the problem. Given an integer sequence a 1, a 2, -, a n, let S(i) = {j|1<=j<i, and a j is a multiple of a i}. If S(i) is not empty, let f(i) be the maximum integer in S(

2014多校训练九(HDU 4960 HDU 4961 HDU 4965 HDU 4968 HDU 4969 HDU 4970)

HDU 4960 Another OCD Patient 题意:给你一串数字  相邻x个数字合并成一个数字(相加)有一定代价  问  最少花费多少使得串变成回文串 思路: 读完题感觉像dp  数据范围也像  就开始想怎么表示状态  最简单的应该想到dp[i][j]表示i到j区间变成回文串的最小花费  状态想好了想做法  考虑将串分成AAAABBBBBBBCCC三段  即所有A合成一个数字  C也是  而且A和C相等  那么B串就变成了子问题  但是A和C是不是都要枚举呢?  这个串所有元素都是正

HDU 4961(杭电多校#9 1002题)Boring Sum(瞎搞)

题目地址:HDU 4961 看来这题的测试数据是随机的.不然出了极限数据还真过不了...这题我的方法是建一个哈希结构体,记录两个变量,分别是num位置,然后是f,f==0表示这个数没出现过,f==1表示这个数出现过.然后分别从前面和后面扫一遍.每次扫的时候,对每一个出现的数都进行标记.然后对当前的数枚举该数的倍数,全部枚举完,取位置num最大的.然后找完之后,对哈希结构体进行更新.如果前面曾经出现过的话,就直接换掉,因为后面的数总比前面的更优.最后扫完两遍之后两个数组就能求出来了.计算就行了.