HDU 5696 区间的价值
来源:互联网 发布:怎样获取网络密码 编辑:程序博客网 时间:2024/05/16 05:31
Problem Description
我们定义“区间的价值”为一段区间的最大值*最小值。
一个区间左端点在L ,右端点在R ,那么该区间的长度为(R−L+1) 。
现在聪明的杰西想要知道,对于长度为k 的区间,最大价值的区间价值是多少。
当然,由于这个问题过于简单。
我们肯定得加强一下。
我们想要知道的是,对于长度为1∼n 的区间,最大价值的区间价值分别是多少。
样例解释:
长度为1 的最优区间为2−2 答案为6∗6
长度为2 的最优区间为4−5 答案为4∗4
长度为3 的最优区间为2−4 答案为2∗6
长度为4 的最优区间为2−5 答案为2∗6
长度为5的最优区间为1−5 答案为1∗6
一个区间左端点在
现在聪明的杰西想要知道,对于长度为
当然,由于这个问题过于简单。
我们肯定得加强一下。
我们想要知道的是,对于长度为
样例解释:
长度为
长度为
长度为
长度为
长度为5的最优区间为
Input
多组测试数据
第一行一个数n(1≤n≤100000) 。
第二行n 个正整数(1≤ai≤109) ,下标从1 开始。
由于某种不可抗力,ai 的值将会是1∼109 内<b style="color:red;">随机产生</b>的一个数。(除了样例)
第一行一个数
第二行
由于某种不可抗力,
Output
输出共n 行,第i 行表示区间长度为i 的区间中最大的区间价值。
Sample Input
51 6 2 4 4
Sample Output
361612126因为数据是随机的,所以可以水过去。
用单调队列的n*n的方法。
#include<map>#include<set>#include<queue>#include<stack>#include<cmath>#include<cstdio>#include<bitset>#include<string>#include<vector>#include<cstring>#include<iostream>#include<algorithm>#include<functional>using namespace std;typedef long long LL;const int low(int x) { return x&-x; }const int INF = 0x7FFFFFFF;const int mod = 1e9 + 7;const int maxn = 2e5 + 10;int n, a[maxn];int p1[maxn],p2[maxn];int l,r,mx,my;int q,h,qq,hh;LL ans;int main(){ while (~scanf("%d",&n)) { l=r=1; for (int i=1;i<=n;i++) { scanf("%d",&a[i]); if (a[i]>a[l]) { l=r=i; mx=my=a[i]; } } printf("%I64d\n",ans=(LL)a[l]*a[r]); for (int i=2;i<=n;i++) { if (l>1&&a[l-1]<=my&&a[l-1]>=mx) { --l; printf("%I64d\n",ans); continue; } if (r<n&&a[r+1]<=my&&a[r+1]>=mx) { ++r; printf("%I64d\n",ans); continue; } q=qq=0; h=hh=-1; ans=0; for (int j=1;j<=n;j++) { while (q<=h&&a[p1[h]]<a[j]) --h; p1[++h]=j; while (qq<=hh&&a[p2[hh]]>a[j]) --hh; p2[++hh]=j; while (p1[q]+i<=j) ++q; while (p2[qq]+i<=j) ++qq; if (j<i) continue; if ((LL)a[p1[q]]*a[p2[qq]]>ans) { ans=(LL)a[p1[q]]*a[p2[qq]]; l=j-i+1; r=j; my=a[p1[q]]; mx=a[p2[qq]]; } } printf("%I64d\n",ans); } } return 0;}
这个问题可以从每个数来考虑,假设他是最小的数,那么左右分别可以到哪里,然后计算最大值,根据区间的递减性质更新回去即可。#pragma comment(linker, "/STACK:1024000000,1024000000")#include<map>#include<set>#include<queue>#include<stack>#include<cmath>#include<cstdio>#include<bitset>#include<string>#include<vector>#include<cstring>#include<iostream>#include<algorithm>#include<functional>using namespace std;typedef __int64 LL;const int low(int x) { return x&-x; }const int INF = 0x7FFFFFFF;const int mod = 1e9 + 7;const int maxn = 1e5 + 10;int T, n, a[maxn], L[maxn], R[maxn], dp[maxn][20], lg[maxn];LL ans[maxn];int get(int l, int r){int k = lg[r - l + 1];return max(dp[l][k], dp[r - (1 << k) + 1][k]);}int main(){lg[1] = 0;for (int i = 2; i < maxn; i++) lg[i] = lg[i >> 1] + 1;while (scanf("%d", &n) != EOF){for (int i = 1; i <= n; i++) scanf("%d", &a[i]), dp[i][0] = a[i], ans[i] = 0;for (int i = 1; (1 << i) <= n; i++){for (int j = 1; j + (1 << i) - 1 <= n; j++){dp[j][i] = max(dp[j][i - 1], dp[j + (1 << i - 1)][i - 1]);}}stack<int> p;for (int i = 1; i <= n; i++){while (!p.empty() && a[p.top()] > a[i]){R[p.top()] = i - 1; p.pop();}p.push(i);}while (!p.empty()) R[p.top()] = n, p.pop();for (int i = n; i; i--){while (!p.empty() && a[p.top()] > a[i]){L[p.top()] = i + 1; p.pop();}p.push(i);}while (!p.empty()) L[p.top()] = 1, p.pop();for (int i = 1; i <= n; i++){int len = R[i] - L[i] + 1;ans[len] = max(ans[len], 1LL * a[i] * get(L[i], R[i]));}for (int i = n - 1; i; i--) ans[i] = max(ans[i], ans[i + 1]);for (int i = 1; i <= n; i++) printf("%I64d\n", ans[i]);}return 0;}
0 0
- HDU 5696 区间的价值
- HDU 5696 区间的价值
- HDU 5696 区间的价值
- HDU 5696 区间的价值
- HDU 5696 区间的价值 (DFS)
- HDU-5696-区间的价值(DFS)
- [HDU 5696] 区间的价值 (单调栈+RMQ)
- hdu 区间的价值(RMQ+扫描)
- HDU 5696 区间的价值 (百度之星2B)
- QAQ的区间价值
- QAQ的区间价值
- 区间的价值 V2
- 区间顺序枚举 hdu5696 区间的价值
- 51nod区间的价值
- Hdu5696 区间的价值(花式水)
- 分治法 区间的价值 hdu5696
- 51NOD AGT19A 区间的价值 V2
- 51NOD 1674 区间的价值 V2
- thinkphp集成系列之短信验证码、订单通知
- 《java入门第一季》之ArrayList集合小案例
- md5密码加盐
- ios 加载进度动画——圆型加载进度方式浅析
- Java做界面思路整理
- HDU 5696 区间的价值
- Linux C笔记之 链接属性 详解
- 傅里叶变换
- R语言-聚类分析
- android事件分发机制详解
- thinkphp集成系列之rbac的升级版auth权限管理系统demo
- windows电脑使用Android studio添加依赖
- IT职业的发展前景
- 专题三1024