http://acm.hdu.edu.cn/showproblem.php?pid=5696

这是这次百度之星初赛2B的第一题,但是由于正好打省赛,于是便错过了。加上2A的时候差了一题,当时有思路,但是代码就是过不去。。这次应该是无缘复赛了。。

先不水了,省赛回来,我看了一下这个题,当时有个类似于快排的想法,今天试了一下,勉强AC了。。跑了3S多。

思路就是我枚举区间左值lt,那么[lt, n]区间内最值的角标分别为mi和ma。于是设to = max(mi, ma)。也就是说在to右侧的所有区间[lt, i]的值至少都是a[mi]*a[ma]。用线段树维护长度为i区间的最值,那么我需要用a[mi]*a[ma]去更新区间[to-lt+1, rt-lt+1]在线段树中的值。然后区间就可以缩减为[lt, to-1]了,于是递归求解就可以了,当然此处可以迭代。

关键是上述的递归过程最多需要运行多少次?

首先to这个位置,要么是mi,要么是ma,也就是说左侧的数据要么都比to这个位置的数小,要么都比它大。光看左侧,这个to很像快排一次运行的那个分隔值。那么to平均下来应该是(lt+rt)/2。

那么总的复杂度就是nlognlogn.

但是此处线段树常数较大,所以需要减一下枝,就是当更新值pls比子树中任意值都小,就可以不用更新,维护子树的最小值就可以了。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <string>
#define LL long long using namespace std; const int maxN = ;
int n, a[maxN]; //RMQ-ST算法
//效率nlogn
//查询区间最值,注意区间[0, n-1]和[1, n]的区别
int ma[maxN][], mi[maxN][]; void RMQ()
{
memset(ma, , sizeof(ma));
memset(mi, , sizeof(mi));
for (int i = ; i <= n; ++i)
mi[i][] = ma[i][] = i;
for (int j = ; (<<j) <= n; ++j)
for (int i = ; i+(<<j)- <= n; ++i)
{
if (a[ma[i][j-]] >= a[ma[i+(<<(j-))][j-]])
ma[i][j] = ma[i][j-];
else
ma[i][j] = ma[i+(<<(j-))][j-];
if (a[mi[i][j-]] <= a[mi[i+(<<(j-))][j-]])
mi[i][j] = mi[i][j-];
else
mi[i][j] = mi[i+(<<(j-))][j-];
}
} int queryMax(int lt, int rt)
{
int k = ;
while ((<<(k+)) <= rt-lt+)
k++;
if (a[ma[lt][k]] >= a[ma[rt-(<<k)+][k]])
return ma[lt][k];
else
return ma[rt-(<<k)+][k];
} int queryMin(int lt, int rt)
{
int k = ;
while ((<<(k+)) <= rt-lt+)
k++;
if (a[mi[lt][k]] <= a[mi[rt-(<<k)+][k]])
return mi[lt][k];
else
return mi[rt-(<<k)+][k];
} //线段树
//求区间最值
struct node
{
int lt, rt;
LL val, delta;
}tree[*maxN]; //向下更新
void pushDown(int id)
{
if (tree[id].delta != )
{
tree[id<<].val = tree[id<<].delta = max(tree[id<<].val, tree[id].delta);
tree[id<<|].val = tree[id<<|].delta = max(tree[id<<|].val, tree[id].delta);
tree[id].delta = ;
}
} //向上更新
void pushUp(int id)
{
tree[id].val = min(tree[id<<].val, tree[id<<|].val);
} //建立线段树
void build(int lt, int rt, int id)
{
tree[id].lt = lt;
tree[id].rt = rt;
tree[id].val = ;//每段的初值,根据题目要求
tree[id].delta = ;
if (lt == rt)
{
//tree[id].delta = ??;
return;
}
int mid = (lt+rt)>>;
build(lt, mid, id<<);
build(mid+, rt, id<<|);
} //增加区间内每个点固定的值
void change(int lt, int rt, int id, LL pls)
{
if (pls <= tree[id].val) return;
if (lt <= tree[id].lt && rt >= tree[id].rt)
{
tree[id].val = tree[id].delta = max(tree[id].delta, pls);
return;
}
pushDown(id);
int mid = (tree[id].lt+tree[id].rt)>>;
if (lt <= mid)
change(lt, rt, id<<, pls);
if (rt > mid)
change(lt, rt, id<<|, pls);
pushUp(id);
} //查询某段区间内的最值
LL query(int lt, int rt, int id)
{
if (lt <= tree[id].lt && rt >= tree[id].rt)
return tree[id].val;
pushDown(id);
int mid = (tree[id].lt+tree[id].rt)>>;
if (rt <= mid)
return query(lt, rt, id<<);
if (lt > mid)
return query(lt, rt, id<<|);
return max(query(lt, mid, id<<), query(mid+, rt, id<<|));
} void input()
{
for (int i = ; i <= n; ++i) scanf("%d", &a[i]);
RMQ();
build(, n, );
} int cnt; void cal(int lt, int rt)
{
int to, mi, ma;
while (lt <= rt)
{
mi = queryMin(lt, rt);
ma = queryMax(lt, rt);
to = max(mi, ma);
change(to-lt+, rt-lt+, , (LL)a[mi]*a[ma]);
rt = to-;
}
} void work()
{
cnt = ;
for (int i = ; i <= n; ++i)
cal(i, n);
for (int i = ; i <= n; ++i)
printf("%lld\n", query(i, i, ));
} int main()
{
//freopen("test.out", "w", stdout);
//freopen("test.in", "r", stdin);
while (scanf("%d", &n) != EOF)
{
input();
work();
}
return ;
}

ACM学习历程—HDU5696 区间的价值(分治 && RMQ && 线段树 && 动态规划)的更多相关文章

  1. ACM学习历程—Codeforces 446C DZY Loves Fibonacci Numbers(线段树 && 数论)

    Description In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence ...

  2. ACM学习历程——HDU2227 Find the nondecreasing subsequences(线段树 && dp)

    Description How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., ...

  3. ACM学习历程——POJ3321 Apple Tree(搜索,线段树)

          Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will ...

  4. ACM学习历程—HDU5700 区间交(树状数组 && 前缀和 && 排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=5700 这是这次百度之星初赛2B的第五题.省赛回来看了一下,有这样一个思路:对于所有的区间排序,按左值排序. 然后 ...

  5. ACM学习历程—HDU5592 ZYB's Premutation(逆序数 && 树状数组 && 二分)(BestCoder Round #65 1003)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5592 题目大意就是给了每个[1, i]区间逆序对的个数,要求复原原序列. 比赛的时候2B了一发. 首先 ...

  6. ACM学习历程—HDU 5536 Chip Factory(xor && 字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题目大意是给了一个序列,求(si+sj)^sk的最大值. 首先n有1000,暴力理论上是不行的. ...

  7. ACM学习历程—HDU 5443 The Water Problem(RMQ)(2015长春网赛1007题)

    Problem Description In Land waterless, water is a very limited resource. People always fight for the ...

  8. ACM学习历程——UVA11234 Expressions(栈,队列,树的遍历,后序遍历,bfs)

    Description   Problem E: Expressions2007/2008 ACM International Collegiate Programming Contest Unive ...

  9. ACM学习历程—HDU 5317 RGCDQ (数论)

    Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more an ...

随机推荐

  1. CSS清除浮动使父级元素展开的三个方法

    点评:一个没有设置高度的容器div内如果存在浮动元素(即使用了属性float:left或者float:right),那么该父级元素会无法展开,下面举个例子为大家详细介绍下,希望对大家有所帮助 一个没有 ...

  2. iOS 当公司有人向你提问,你该如何应对?

    今天 因为iOS 开发的内部版本号耿耿于怀好久,释然后让我有了一个新想法:从前,能让我兴奋的点是解决一个有一个拗脑筋的问题,见大部分博客便知,都是技术方面的积累. 那么从今天起我决定让自己有个新起点, ...

  3. Python编程-常用模块及方法

    常用模块介绍 一.time模块 在Python中,通常有这几种方式来表示时间: 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量.我们运行 ...

  4. nodejs安装,配置环境,使用express建立一个新项目

    1.下载nodejs安装包 去nodejs官网下载最新版本就行,网址:http://nodejs.cn/download/,点击自己适用的系统,自动下载跟电脑操作系统位数符合的安装包, 下载下来安装包 ...

  5. 仿Facebook登录表单

    在线演示 本地下载

  6. jsonp跨域总结

    同源限制: 浏览器不允许一个域的脚本请求另一个域的文档,通俗来说,不允许访问不同协议.不同域名或不同端口的文档 跨域处理方法: 1.jsonp 前提: 浏览器虽然对ajax请求做出了限制,但scrip ...

  7. ceph安装各种报错

    [ceph_deploy][ERROR ] RuntimeError: Failed to execute command: ceph-disk-activate –mark-init sysvini ...

  8. javax.servlet.jsp.JspException cannot be resolved to a type 和 javax.servlet.jsp.PageContext cannot be resolved to a type 解决办法

    今天我从码云上拉一个项目下来,是个maven项目,闲来无事自己研究研究,发现刚拉下来,项目就有报错,我一看是httpServletRequest cannot be resolved to a typ ...

  9. 未能将网站配置为使用ASP.NET4.X 解决方法

    WIN 10系统安装Visual Studio 2012新建ASP.NET MVC 4 WEB 应用程序出错 有些图片是网上截取而来,之前光顾着处理问题而忘记截图了,提示的ASP.net 版本有些不同 ...

  10. hadoop 知识点总结

    关于元数据的checkpoint 每隔一段时间,会由secondary namenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge(这个过 ...