hdu4961 Boring Sum(数学)
来源:互联网 发布:魔兽世界网络卡 编辑:程序博客网 时间:2024/05/17 01:57
题目:
Boring Sum
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1213 Accepted Submission(s): 569
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 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.
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.
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.
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
51 4 2 3 90
Sample Output
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.
Author
SYSU
Source
2014 Multi-University Training Contest 9
思路:其实就是怎么快速找出最靠近一个数并且是它倍数的数。我们可以先暴力枚举出每个数的约数(用类似素数筛法的方法,nlogn),然后用一个数组来维护一个约数最后出现的位置。先从左往右枚举数组中的每一个元素,如果它已经出现在了约数数组里,那么对应的约数数组的值就是它的左边最靠近它的倍数的下标。然后将它的左右约数填进约数数组里。再从右往左枚举数组就得到了它的右边最靠近它的倍数的下标。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<vector>using namespace std;const int MAXN=100000;int a[MAXN+5];vector<int>f[MAXN+5];int F[MAXN+5],G[MAXN+5];int b[MAXN+5],c[MAXN+5];void init(){for(int i=1;i<=MAXN;i++)f[i].clear();for(int i=1;i<=MAXN;i++)for(int j=i;j<=MAXN;j+=i)f[j].push_back(i);}int vis[MAXN+5];int main(){int n;init();while(scanf("%d",&n)!=EOF){if(!n)break;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]]){vis[a[i]]=i;F[i]=i;}else{F[i]=vis[a[i]];vis[a[i]]=i;}for(int j=0;j<f[a[i]].size();j++){vis[f[a[i]][j]]=i;}}//printf("%d ",F[i]);//printf("\n");memset(vis,0,sizeof(vis));for(int i=n;i>=1;i--){if(!vis[a[i]]){vis[a[i]]=i;G[i]=i;}else{G[i]=vis[a[i]];}for(int j=0;j<f[a[i]].size();j++){vis[f[a[i]][j]]=i;}}__int64 ans=0;for(int i=1;i<=n;i++){b[i]=a[F[i]];c[i]=a[G[i]];ans=ans+(__int64)b[i]*c[i];}printf("%I64d\n",ans);}return 0;}
0 0
- hdu4961 Boring Sum(数学)
- HDU4961 Boring Sum
- HDU4961:Boring Sum
- hdu4961-Boring Sum
- hdu4961 Boring Sum
- HDU4961-Boring Sum(质因子)
- Boring Sum(hdu4961)hash
- 2014多校1002--hdu4961--Boring Sum
- HDU4961——Boring Sum(数论)
- Boring Sum
- hdu4961
- HDU 4961 Boring Sum
- HDU - 4961 Boring Sum
- hdu 4961 Boring Sum
- hdu 4961 Boring Sum
- HDOJ-4961 Boring Sum
- hdu 4961 Boring Sum
- HDU 4961 Boring Sum
- 基于MVC4+EasyUI的Web开发框架形成之旅--界面控件的使用
- 数据库课程设计
- MVC模式和文档/视图结构
- iOS学习8:iOS沙盒(sandBox)机制(二)之沙盒文件操作
- Java第一周:1.4
- hdu4961 Boring Sum(数学)
- iOS开发笔记之NSFileManager的使用
- J2SE_数组学习笔记
- Linux内核最新的连续内存分配器(CMA)——避免预留大块内存
- Java第一周:1.5
- BestCoder Round #54 (div.2) HDOJ 5427 A problem of sorting(模拟)
- UISegmentedControl的详细使用
- CCLabelAtlas,CCLabelTextFormatter解析
- 【各种系列教程】fms p2p视频教程 第二节FMS通信