HDU-4961 Boring Sum STL模拟

给出一个序列A,对于A里面的每个元素,左边最近的能被它整除的元素记为B序列对应位置的,右边最近的是它的整数倍的元素记为C序列对应位置,找不到的记它本身,最后算出对应位置B*C的总和。

容器模拟,按顺序扫一遍,每次如果有符合条件的取出来,即为最近的。最后把它的下标放到对应位置的容器中,然后倒序求一遍,最后求和。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>
#include <iomanip>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=100010;
vector<int>p[maxn];
int n;
int a[maxn];
int b[maxn];
int c[maxn];
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0)
		{
			break;
		}
		for(int i=0;i<maxn;i++)
		{
			p[i].clear();
		}
		memset(b,-1,sizeof(b));
		memset(c,-1,sizeof(c));
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
		c[n-1]=n-1;
		p[a[0]].push_back(0);
		for(int i=1;i<n;i++)
		{
			for(int j=1;j<=sqrt(a[i]);j++)
			{
				int u=j;
				if(a[i]%j==0)
				{
					for(int k=0;k<p[u].size();k++)
					{
						c[p[u][k]]=i;
					}
					p[u].clear();
					int v=a[i]/j;
					for(int k=0;k<p[v].size();k++)
					{
						c[p[v][k]]=i;
					}
					p[v].clear();
				}
			}
			p[a[i]].push_back(i);
		}
		for(int i=0;i<maxn;i++)
		{
			p[i].clear();
		}
		b[0]=0;
		p[a[n-1]].push_back(n-1);
		for(int i=n-2;i>=0;i--)
		{
			for(int j=1;j<=sqrt(a[i]);j++)
			{
				int u=j;
				if(a[i]%j==0)
				{
					for(int k=0;k<p[u].size();k++)
					{
						b[p[u][k]]=i;
					}
					p[u].clear();
					int v=a[i]/j;
					for(int k=0;k<p[v].size();k++)
					{
						b[p[v][k]]=i;
					}
					p[v].clear();
				}
			}
			p[a[i]].push_back(i);
		}
		for(int i=0;i<n;i++)
		{
			if(b[i]==-1)
			{
				b[i]=i;
			}
			if(c[i]==-1)
			{
				c[i]=i;
			}
		}
		long long sum=0;
		for(int i=0;i<n;i++)
		{
			sum+=(long long)a[b[i]]*a[c[i]];
		}
		printf("%I64d\n",sum);
	}
	return 0;
}
时间: 2024-12-17 05:26:32

HDU-4961 Boring Sum STL模拟的相关文章

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

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是不是都要枚举呢?  这个串所有元素都是正