hdu 4961 Boring Sum 多校九

HDU4961题解
本文介绍了解决HDU4961问题的方法,通过记录每个数倍数的位置并使用二分查找来确定左右边界,从而计算bi*ci之和。提供了完整的C++实现代码。

题目链接:hdu 4961

        bi表示第i位左边最靠右的ai的倍数,ci表示第i位右边最靠左的ai的倍数求bi*ci的和

        开一个vector,p[i]记录i的倍数的所有位置,然后从前向后扫一边找出每个数倍数左边以及右边的数即可

/******************************************************
 * File Name:   1002.cpp
 * Author:      kojimai
 * Creater Time:2014年08月19日 星期二 13时22分49秒
 ******************************************************/

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
#define FFF 100005
long long a[FFF];
vector<int> p[100005];
int qfind(int x)
{
	int l=0,r=p[a[x]].size()-1,mid;
	while(l<=r)
	{
		mid=(l+r)/2;
		if(p[a[x]][mid]==x)
			return mid;
		else if(p[a[x]][mid]<x)
			l=mid+1;
		else
			r=mid-1;
	}
}
int main()
{
	int n;
	while(scanf("%d",&n),n)
	{
		for(int i=1;i<100005;i++)
			p[i].clear();
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			p[a[i]].push_back(i);
			for(int j=2;j*j<=a[i];j++)
			{
				if(a[i]%j==0)
				{
					p[j].push_back(i);
					if(j*j!=a[i])
						p[a[i]/j].push_back(i);
				}
			}
		}
		long long ans=0;
		for(int i=1;i<=n;i++)
		{
			int l,r;
			if(a[i]==1)
			{
				if(i==1)
					l=1;
				else
					l=i-1;
				if(i==n)
					r=i;
				else
					r=i+1;
			}
			else
			{

				int x=qfind(i);
				if(x==0)
					l=i;
				else
					l=p[a[i]][x-1];
				if(x==p[a[i]].size()-1)
					r=i;
				else
					r=p[a[i]][x+1];
			}
			ans+=a[l]*a[r];

		}
		cout<<ans<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值