hdu 4961 Boring Sum(数学题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4961
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 bi 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 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.
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.
5
1 4 2 3 9
0
136HintIn 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.
题意:
给出一个数列: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(数学题)的更多相关文章
- hdu 4961 Boring Sum(高效)
pid=4961" target="_blank" style="">题目链接:hdu 4961 Boring Sum 题目大意:给定ai数组; ...
- hdu 4961 Boring Sum
Boring Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tota ...
- hdu 4961 Boring Sum (思维 哈希 扫描)
题目链接 题意:给你一个数组,让你生成两个新的数组,A要求每个数如果能在它的前面找个最近的一个是它倍数的数,那就变成那个数,否则是自己,C是往后找,输出交叉相乘的和 分析: 这个题这种做法是O(n*s ...
- HDOJ 4961 Boring Sum
Discription Number theory is interesting, while this problem is boring. Here is the problem. Given a ...
- HDU 1024 Max Sum Plus Plus --- dp+滚动数组
HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...
- HDU 1003 Max Sum --- 经典DP
HDU 1003 相关链接 HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...
- HDU 1244 Max Sum Plus Plus Plus
虽然这道题看起来和 HDU 1024 Max Sum Plus Plus 看起来很像,可是感觉这道题比1024要简单一些 前面WA了几次,因为我开始把dp[22][maxn]写成dp[maxn][2 ...
- hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)
题目链接:hdu 3415 Max Sum of Max-K-sub-sequence 题意: 给你一串形成环的数,让你找一段长度不大于k的子段使得和最大. 题解: 我们先把头和尾拼起来,令前i个数的 ...
- 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 ...
随机推荐
- poj1860 解题报告
题意:这里有N种货币,分别记为1~N,有M种货币交换的方式,每一种方式有A,B两种钱币,有RAB, CAB, RBA and CBA,四个数,表示交换率, Nick手上有其中的一种货币S,货币S的钱数 ...
- Nginx负载均衡:分布式/热备Web Server的搭建
Nginx是一款轻量级的Web server/反向代理server及电子邮件(IMAP/POP3)代理server.并在一个BSD-like 协议下发行.由俄罗斯的程序设计师Igor Sysoev所开 ...
- 节点地址的函数list_entry()原理详解
本节中,我们继续讲解,在linux2.4内核下,如果通过一些列函数从路径名找到目标节点. 3.3.1)接下来查看chached_lookup()的代码(namei.c) [path_walk()> ...
- SuperSocket应用之FTP源码解析
一 简述 命令行协议是一种使用比较多的协议,其优点在于使用简单易于扩展性,同时也利于解析和使用.FTP,POP,SMTP等均采用命令行协议,其中FTP在早起互联网时期成为网络资源共享的主要方式,可见F ...
- UVA11069 - A Graph Problem(DP)
UVA11069 - A Graph Problem(DP) 题目链接 题目大意:给你n个点.要你找出有多少子串符合要求.首先没有连续的数字,其次不能再往里面加入不论什么的数字而不违反第一条要求. 解 ...
- 全局忽略编译警告(设置QMAKE_CXXFLAGS )
msvc编译器从2010 sp1开始就已经支持UTF-8的源码文件了,然后到vs2012又不支持了,官方表示是BUG.到目前最新的vs2013就解决了这个问题... 但是在编译时仍然会出现4819的警 ...
- 003.android资源文件剖析(Resources)
android的资源文件使用的重要性,不言而喻.让我们从潜到深逐渐来了解吧. 一:android的基本资源: 1.字符串资源 android的资源文件保存在:res\values\ 2.布局资源 an ...
- C语言 realloc为什么要有返回值,realloc返回值具体解释/(解决随意长度字符串输入问题)。
在C语言操作中会用到大量的内存操作,当中非经常常使用的一个是realloc(). 由字面意思能够知道,该函数的作用是用于又一次分配内存. 使用方式例如以下: NewPtr=(数据类型*)realloc ...
- Delphi控件的停靠功能
Delphi自带的许多控件都有停靠功能,而且操作非常简单,大可不必选用第三方控件. 基本上,要进行Dock操作至少需要两个组件,一个人被附着的Dock Site组件,另一个人附在Dock ...
- leetcode第一刷_Largest Rectangle in Histogram
非常难的问题,数组线性时间. 属于我之前说的解法的借助辅助空间.给定两个柱子,他们之间的面积由什么确定呢?没错,他们之间的距离和他们之间最矮的那个柱子的高度.我们并不知道这个柱子在什么位置,所以仅仅能 ...