HDU-4961 Boring Sum STL模拟

本文介绍了一种算法,该算法通过寻找序列中每个元素左侧最近的因子和右侧最近的倍数,并计算所有元素对应的乘积之和。采用容器模拟的方式实现,先正向扫描再逆向扫描以确定每个位置的因子和倍数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给出一个序列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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值