HDU5696 区间的价值

传送门

一道比较基础的分治题……但是我似乎不会分治……

首先,区间的价值肯定与最小值有关,所以对于当前处理的区间,我们首先暴力的求出区间的最小值,其位置记为pos。之后……对于一个横跨过pos的区间,它的价值必定可以由pos左右两边区间的价值更新而来,所以说我们只需要暴力的在左右两边O(n)的扫一遍求出相应的长度的区间价值最大值,之后用较短的区间的价值更新较长的即可。

之后再递归分治pos的左右两边的区间即可。

本题的关键在于,能通过找到pos这个位置,之后把横跨过pos的区间的值由左右两边更新。但是其实这个方法挺不稳定的orzzzz,幸好都是随机数据,能过……

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar(‘\n‘)
#define fr friend inline
#define y1 poj
#define mp make_pair
#define pr pair<int,int>
#define fi first
#define sc second
#define pb push_back
#define lowbit(x) x & (-x)

using namespace std;
typedef long long ll;
const int M = 200005;
const int INF = 1000000009;
const double eps = 1e-7;

ll read()
{
    ll ans = 0,op = 1;
    char ch = getchar();
    while(ch < ‘0‘ || ch > ‘9‘)
    {
    if(ch == ‘-‘) op = -1;
    ch = getchar();
    }
    while(ch >= ‘0‘ && ch <= ‘9‘)
    {
    ans *= 10;
    ans += ch - ‘0‘;
    ch = getchar();
    }
    return ans * op;
}

ll n,a[M],pos,tmp[M],ans[M];

void solve(ll l,ll r)
{
   if(l > r) return;
   ll len = r - l + 1,pos = l,cur = 0;
   rep(i,1,len) tmp[i] = 0;
   rep(i,l,r) if(a[i] < a[pos]) pos = i;
   rep(i,l,pos) tmp[pos - l + 1] = max(tmp[pos - l + 1],a[i] * a[pos]);
   rep(i,pos+1,r) tmp[r - pos + 1] = max(tmp[r - pos + 1],a[i] * a[pos]);
   rep(i,1,len)
   {
      cur = max(cur,tmp[i]);
      ans[i] = max(ans[i],cur);
   }
   solve(l,pos-1),solve(pos+1,r);
}

int main()
{
   while(scanf("%lld",&n) != EOF)
   {
      rep(i,1,n) a[i] = read();
      solve(1,n);
      rep(i,1,n) printf("%lld\n",ans[i]);
   }
   return 0;
}

原文地址:https://www.cnblogs.com/captain1/p/10086508.html

时间: 2024-11-09 10:30:37

HDU5696 区间的价值的相关文章

hdu5696区间的价值 -- 2016&quot;百度之星&quot; - 初赛(Astar Round2B)

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 长度

ACM学习历程—HDU5696 区间的价值(分治 &amp;&amp; RMQ &amp;&amp; 线段树 &amp;&amp; 动态规划)

http://acm.hdu.edu.cn/showproblem.php?pid=5696 这是这次百度之星初赛2B的第一题,但是由于正好打省赛,于是便错过了.加上2A的时候差了一题,当时有思路,但是代码就是过不去..这次应该是无缘复赛了.. 先不水了,省赛回来,我看了一下这个题,当时有个类似于快排的想法,今天试了一下,勉强AC了..跑了3S多. 思路就是我枚举区间左值lt,那么[lt, n]区间内最值的角标分别为mi和ma.于是设to = max(mi, ma).也就是说在to右侧的所有区间

51nod 1674 区间的价值V2(思维+拆位+尺取法)

最近被四区题暴虐... 题意:lyk拥有一个区间. 它规定一个区间的价值为这个区间中所有数and起来的值与这个区间所有数or起来的值的乘积. 例如3个数2,3,6.它们and起来的值为2,or起来的值为7,这个区间对答案的贡献为2*7=14. 现在lyk有一个n个数的序列,它想知道所有n*(n+1)/2个区间的贡献的和对1000000007取模后的结果是多少. 区间的and值和区间的or值相乘,实际上等于将and值分解为2的幂次和的形式与or值分解成2的幂次和的形式相乘. 所以对于同一段区间来说

hdu 5696 区间的价值 单调栈+rmq

区间的价值 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description 我们定义“区间的价值”为一段区间的最大值*最小值. 一个区间左端点在L,右端点在R,那么该区间的长度为(R−L+1). 现在聪明的杰西想要知道,对于长度为k的区间,最大价值的区间价值是多少. 当然,由于这个问题过于简单. 我们肯定得加强一下. 我们想要知道的是,对于长度为1∼n

区间的价值(线段树)百度之星

区间的价值 Accepts: 0 Submissions: 0 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 我们定义“区间的价值”为一段区间的最大值*最小值. 一个区间左端点在LLL,右端点在RRR,那么该区间的长度为(R−L+1)(R-L+1)(R−L+1). 现在聪明的杰西想要知道,对于长度为kkk的区间,最大价值的区间价值是多少.

1674 区间的价值 V2(分治)

1674 区间的价值 V2 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 lyk拥有一个区间. 它规定一个区间的价值为这个区间中所有数and起来的值与这个区间所有数or起来的值的乘积. 例如3个数2,3,6.它们and起来的值为2,or起来的值为7,这个区间对答案的贡献为2*7=14. 现在lyk有一个n个数的序列,它想知道所有n*(n+1)/2个区间的贡献的和对1000000007取模后的结果是多少. 例如当这个序列为{3,4,5}时,那么区间[1,1],

HDU 5696 ——区间的价值——————【线段树、快排思想】

区间的价值 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 662    Accepted Submission(s): 329 Problem Description 我们定义“区间的价值”为一段区间的最大值*最小值. 一个区间左端点在L,右端点在R,那么该区间的长度为(R−L+1). 现在聪明的杰西想要知道,对于长度为k的区间,最大

[hdu] 5696 区间的价值 || 序列分治

原题 我们定义"区间的价值"为一段区间的最大值*最小值. 一个区间左端点在L,右端点在R,那么该区间的长度为(R?L+1). 求长度分别为1-n的区间的最大价值. 保证数据随机 因为保证数据随机,所以我们可以考虑用区间的最大值把这个区间分为两个部分,这样答案的贡献就有两种情况. 1.在同一个区间里 2.跨过最大值,在两个区间里 情况1通过递归就变成了情况2,而情况二我们通过two-points来完成.记录l指针和r指针,因为所求为最大值,所以选取l和r指针较大的内个加入,并每次更新答案

51nod1674:区间的价值2(分治,利用&amp;和|的收敛性)

lyk拥有一个区间. 它规定一个区间的价值为这个区间中所有数and起来的值与这个区间所有数or起来的值的乘积. 例如3个数2,3,6.它们and起来的值为2,or起来的值为7,这个区间对答案的贡献为2*7=14. 现在lyk有一个n个数的序列,它想知道所有n*(n+1)/2个区间的贡献的和对1000000007取模后的结果是多少. 例如当这个序列为{3,4,5}时,那么区间1,11,1,1,21,2,1,31,3,2,22,2,2,32,3,3,33,3的贡献分别为9,0,0,16,20,25.