题目链接: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(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
Hint
In the sample, b1=1, c1=4, b2=4, c2=4, b3=4, c3=2, b4=3, c4=9, b5=9, c5=9, so b1 * c1 + b2 * c2 + … + b5 * c5 = 136.
 
Author
SYSU
 
Source

题意:

给出一个数列:a[i],然后

b[i]:表示在 i 前面的项,假设有a[i]的倍数(要最靠近i的),那么b[i]就等于这个数,假设没有那么b[i] = a[i];

c[i]:表示在 i 后面的项,假设有a[i]的倍数(要最靠近i的),那么c[i] 就等于这个数,假设没有那么c[i] = a[i];

思路:

//先打表,把每一个数的约数存在vector里;

//然后从前往后扫一遍,结果存在b[i],

//Ps:假设不清楚为什么从前往后扫一遍就是最靠近的那个数可调试一下(案例:9 6 3 2 1);

//然后从后往前扫一遍,结果存在c[i],

//Ps:假设不清楚为什么从后往前扫一遍就是最靠近的那个数可调试一下(案例:1 2 3 6 9);

//最后计算b[i]*c[i]的和就可以。

代码例如以下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define maxn 100000+17
using namespace std;
typedef __int64 LL;
int vis[maxn];
int a[maxn], b[maxn], c[maxn];
vector<int>V[maxn];
void init()
{
for(int i = 0; i < maxn; i++)
V[i].clear();
for(int i = 1; i <= maxn; i++)
{
for(int j = 1; j*i <= maxn; j++)//每一个数对应的约数
{
V[i*j].push_back(i);//i是哪些数的约数
}
}
}
int main()
{
int n;
init();
while(scanf("%d",&n) && n)
{
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]] == 0)
b[i]=a[i];
else
b[i]=vis[a[i]];//a[i]的倍数
for(int j = 0; j < V[a[i]].size(); j++)
vis[V[a[i]][j]] = a[i];//V[a[i]][j]为a[i]的约数
}
memset(vis,0,sizeof(vis));
for(int i = n; i >= 1; i--)
{
if(vis[a[i]] == 0)
c[i] = a[i];
else
c[i] = vis[a[i]];
for(int j = 0; j < V[a[i]].size(); j++)
vis[V[a[i]][j]] = a[i];
}
LL sum=0;
for(int i = 1; i <= n; i++)
{
sum += (LL)b[i]*(LL)c[i];
}
printf("%I64d\n",sum);
}
return 0;
}

hdu 4961 Boring Sum(数学题)的更多相关文章

  1. hdu 4961 Boring Sum(高效)

    pid=4961" target="_blank" style="">题目链接:hdu 4961 Boring Sum 题目大意:给定ai数组; ...

  2. hdu 4961 Boring Sum

    Boring Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tota ...

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

    题目链接 题意:给你一个数组,让你生成两个新的数组,A要求每个数如果能在它的前面找个最近的一个是它倍数的数,那就变成那个数,否则是自己,C是往后找,输出交叉相乘的和 分析: 这个题这种做法是O(n*s ...

  4. HDOJ 4961 Boring Sum

    Discription Number theory is interesting, while this problem is boring. Here is the problem. Given a ...

  5. HDU 1024 Max Sum Plus Plus --- dp+滚动数组

    HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...

  6. HDU 1003 Max Sum --- 经典DP

    HDU 1003    相关链接   HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...

  7. HDU 1244 Max Sum Plus Plus Plus

    虽然这道题看起来和 HDU 1024  Max Sum Plus Plus 看起来很像,可是感觉这道题比1024要简单一些 前面WA了几次,因为我开始把dp[22][maxn]写成dp[maxn][2 ...

  8. hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)

    题目链接:hdu 3415 Max Sum of Max-K-sub-sequence 题意: 给你一串形成环的数,让你找一段长度不大于k的子段使得和最大. 题解: 我们先把头和尾拼起来,令前i个数的 ...

  9. HDU 1024 Max Sum Plus Plus (动态规划)

    HDU 1024 Max Sum Plus Plus (动态规划) Description Now I think you have got an AC in Ignatius.L's "M ...

随机推荐

  1. pygame编写贪吃蛇

    一直想用pygame做一个小游戏的,可是因为拖延症的缘故一直没有动,结果那天看到了一个12岁的国际友人小盆友用pygame做的一款塔防游戏,突然感觉已经落后超级远了,所以心血来潮做小游戏了.高中陪伴我 ...

  2. html-图片button,抓包---Shinepans

    askLike.html <html> <meta http-equiv="content-type" content="text/html;chars ...

  3. 利用Android属性动画实现Banner的原理与实践

    事实上在Android刚推出属性动画的时候.就想利用它来设计一个Banner控件,一直没什么时间尝试. 在当时看我们应用中的Banner,使用计时器来控制自己主动播放,设置一个非常大的数,利用余数原理 ...

  4. Effective C++_笔记_条款08_别让异常逃离析构函数

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) C++并不禁止析构函数吐出异常,但它不鼓励你这样做.考虑如下代码 ...

  5. 一次完整的HTTP请求所经历的7个步骤(前三步是浏览器工作,后四步是服务器工作)

    HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤: 1. 建立TCP连接在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连 ...

  6. OWAP Top 10

    2013 Top 10 List   A1-Injection Injection flaws, such as SQL, OS, and LDAP injection occur when untr ...

  7. 在屏幕上建立ALV

    在屏幕上创建两个文本元素空件.一个推出按钮控件.一个定制控制按钮 代码所示: *&------------------------------------------------------- ...

  8. 使用Elasticsearch、Logstash、Kibana与Redis(作为缓冲区)对Nginx日志进行收集(转)

    摘要 使用Elasticsearch.Logstash.Kibana与Redis(作为缓冲区)对Nginx日志进行收集 版本 elasticsearch版本: elasticsearch-2.2.0 ...

  9. ExtJs4 笔记(8) Ext.slider 滚轴控件、 Ext.ProgressBar 进度条控件、 Ext.Editor 编辑控件

    本篇要登场的有三个控件,分别是滚轴控件.进度条控件和编辑控件. 一.滚轴控件 Ext.slider 1.滚轴控件的定义 下面我们定义三个具有代表意义滚轴控件,分别展示滚轴横向.纵向,以及单值.多值选择 ...

  10. Delphi事件的广播2

    上篇文章写了将事件分离成类的方法来实现事件的广播,这次将参考观察者模式来实现事件的广播.模式中主要有这两个角色: 发布者:发布者保存着一张观察者的列表,以便在必要的时候调用观察者的方法. 观察者:观察 ...