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. iOS11 仿大标题 导航栏

    iOS11 SytleTitleController  仿大标题 风格 导航栏 仿 iOS11 大导航标题 风格 UI 适用范围 iOS8 + 前言 iOS11全面应用大标题设计,(岂止于大—— 比逼 ...

  2. flask实现模仿知乎

    上个月花了一个月的时间学习flask框架实现了一个简陋的知乎,有提问,回答,写文章,个人信息页,个人信息修改等功能,因刚接触学习flask,后端代码实现很多冗余,依旧需要修改. github: htt ...

  3. 何为RunLoop?RunLoop有哪些应用场景?

    一.RunLoop的作用 一个应用开始运行以后放在那里,如果不对它进行任何操作,这个应用就像静止了一样,不会自发的有任何动作发生,但是如果我们点击界面上的一个按钮,这个时候就会有对应的按钮响应事件发生 ...

  4. vRO 添加已有磁盘到VM

    在vRO实现将已有虚拟机磁盘添加到另外的虚拟机上,以为vRA发布Oracle/SQL集群做准备: // 脚本需要两个输入 vm_obj和diskPathSystem.log("Attempt ...

  5. SQLite3时间函数小结

    import sqlite3 conn = sqlite3.connect('/tmp/sqlite.db') cur = conn.cursor() 接下来干嘛呢?建一张表吧.这里需要注意的是,SQ ...

  6. Python 数值类型

    1.数值类型分为整形(二进制(0b),八进制(0o),十进制,十六进制(0x) ),浮点型,long,complex(复合行) 当我们说十进制数的时候,是逢10进1,就是说到达10的时候就要向前一位进 ...

  7. poj 2406 Power Strings【字符串+最小循环节的个数】

                                                                                                      Po ...

  8. codeforces 353D 递推 找规律

    题意:一组男生女生在排队,每秒钟所有排在女生左边的男生与她相邻的女生交换位置,求女生全部换到男生前面的时间. 思路: 解法一:队伍最前面的那些女生不需要交换,后面的女生有两种状态:畅通无阻,前一个女生 ...

  9. java异常和错误类总结(2016.5)

    看到以前2016.5.写的一点笔记,拿过来放在一起. java异常和错误类总结 最近由于考试和以前的面试经常会遇到java当中异常类的继承层次的问题,弄得非常头大,因为java的异常实在是有点多,很难 ...

  10. Could not reserve enough space for object heap解决办法

    Centos6.4  Jdk1.6 1.在终端输入Java命令报错 [root@localhost local]# java Error occurred during initialization ...