您的位置:首页 > 其它

HDU 4961 Boring Sum 因数分解

2014-08-20 17:47 337 查看
题意:给出序列,对于每个数ai,求出分别求出他的左边和右边离他最近的且是他倍数的bi,ci,如果没有令bi = ai,或ci = ai. 求出所有bi * ai的和。

思路:对于每个数,他只能成为他的因子的倍数。所以,我们从前往后更新时,对于每个数,将它的所有的因子的坐标跟新为它的坐标,查询离它最近的倍数,也就是查询它作为因子,在它左面的数中,是否有数成为它的倍数,即:在记录数组中,对应的位置是否有合法的坐标。

代码如下:

#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
const int maxn=100005;
int a[maxn];
int b[maxn];
int c[maxn];
int num[maxn];
int n;
vector<int> f[maxn];
void init()
{
int i,j;
for(i=1;i<maxn;i++)
for(j=1;j<=sqrt((double)i);j++)
{
if(i%j==0)
{
f[i].push_back(j);
f[i].push_back(i/j);
}

}
}
int main()
{
init();
while(scanf("%d",&n)&&n)
{
int i,j;
memset(num,0,sizeof(num));
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=n;i++)
{
int sz=f[a[i]].size();
if(num[a[i]]==0) b[i]=a[i];
else b[i]=a[num[a[i]]];
for(j=0;j<sz;j++)
{
num[f[a[i]][j]]=i;
}
}
memset(num,0,sizeof(num));
for(i=n;i>0;i--)
{
int sz=f[a[i]].size();
if(num[a[i]]==0) c[i]=a[i];
else c[i]=a[num[a[i]]];
for(j=0;j<sz;j++)
{
num[f[a[i]][j]]=i;
}
}
long long ans=0;
for(i=1;i<=n;i++)
{
ans=(long long)ans+((long long)b[i]*(long long)c[i]);
}
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: