[CSP-S模拟测试]:小P的单调数列(树状数组+DP)
题目描述
小$P$最近喜欢上了单调数列,他觉得单调的数列具有非常多优美的性质。经过小$P$复杂的数学推导,他计算出了一个单调增数列的艺术价值等于该数列中所有书的总和。并且以这个为基础,小$P$还可以求出任意一个数列的艺术价值,它等于将这个数列顺次划分若干个极长单调区间(相邻两个单调区间的单调性必须不相同)后,每个单调区间中元素总和的平均值。比如对于数列$3\ 7\ 9\ 2\ 4\ 5$,它将被划分为$[3\ 7\ 9]\ [2]\ [4\ 5]$,其艺术价值为$\frac{19+2+9}{3}=10$。 由于小$P$的审美观,他还要求划分出的第一个单调区间必须为单调增区间,也就是说,对于数列$10\ 9\ 8$,它将被划分为$[10]\ [9\ 8]$,而不是$[10\ 9\ 8]$。
现在小$P$手里有一个长度为$n$的序列$\{a_i\}$,他想问你,这个序列的所有子序列中,艺术价值最大的是哪个子序列,输出其艺术价值。
注意:本体单调数列为严格单调,也就是说数列中的数必须严格上升或严格下降。
输入格式
输入的第一行为一个正整数$n$,表示序列的长度。
接下来的一行为$n$个正整数$a_1,a_2,...,a_n$,代表序列中的$n$个数。
输出格式
输出仅有一个实数,表示子序列的最大艺术价值。
实数四舍五入,保留三位小数。
样例
样例输入1:
4
1 2 5 4
样例输出1:
8.000
样例输入2:
6
3 1 7 2 6 5
样例输出2:
10.500
数据范围与提示
对于第一个样例,最优的子序列为$1\ 2\ 5$,其价值为$8$。如果选择$5\ 4$的话,虽然和为$9$,但单调区间数为$2$,因为第一个单调区间必须为递增区间。
对于第二个样例,最优的子序列为$3\ 7\ 6\ 5$,其价值为$\frac{3+7+6+5}{2}=10.5$。
题解
首先,来看一条性质:一定存在一个最优子序列,它的单调区间长度不超过$2$。
有了这个性质,这道题就简单多了,维护三个树状数组就好了。
下面是某大神总结的树状数组的用途:
$1$:快速简洁求解前缀最值
$2$:快速简洁求解前缀和,单点修改区间和,区间修改单点值。
$3$:并不简洁的求解区间修改区间求和(但也比线段树简洁)
$4$:快速维护树上每个点到根的路径权值和
$5$:快速维护树上每个点的子树和(与$4$不兼容)
$6$:用来轻松愉快的套主席树,$Splay$等各类动态数据结构
$7$:维护带删除\插入操作的排名,不过需要二分,两个$log$不推荐,推荐线段树一个$log$
时间复杂度:$\Theta(n\log n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int n;
int a[100001],b[100001];
long long tr1[100001],tr2[100001],tr3[100001];
double ans;
int lowbit(int x){return x&-x;}
void add1(int x,long long w){for(int i=x;i;i-=lowbit(i))tr1[i]=max(tr1[i],w);}
void add2(int x,long long w){for(int i=x;i<=b[0];i+=lowbit(i))tr2[i]=max(tr2[i],w);}
void add3(int x,long long w){for(int i=x;i;i-=lowbit(i))tr3[i]=max(tr3[i],w);}
long long ask1(int x)
{
long long res=0;
for(int i=x;i<=b[0];i+=lowbit(i))res=max(res,tr1[i]);
return res;
}
long long ask2(int x)
{
long long res=0;
for(int i=x;i;i-=lowbit(i))res=max(res,tr2[i]);
return res;
}
long long ask3(int x)
{
long long res=0;
for(int i=x;i<=b[0];i+=lowbit(i))res=max(res,tr3[i]);
return res;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
b[0]=n;
sort(b+1,b+n+1);
b[0]=unique(b+1,b+b[0]+1)-b-1;
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+b[0]+1,a[i])-b+1;
b[0]++;
for(int i=n;i;i--)
{
long long w1=ask1(a[i]+1),w2=ask2(a[i]-1),w3=ask3(a[i]+1);
ans=max(ans,(1.0*w3+b[a[i]-1])/2.0);
ans=max(ans,(1.0*b[a[i]-1]+w2)/2.0);
ans=max(ans,1.0*w1+b[a[i]-1]);
add1(a[i],b[a[i]-1]+w1);
add2(a[i],b[a[i]-1]+w2);
add3(a[i],b[a[i]-1]+max(w2,w3));
}
printf("%.3lf",ans);
return 0;
}
rp++
[CSP-S模拟测试]:小P的单调数列(树状数组+DP)的更多相关文章
- 【CSP模拟赛】奇怪的队列(树状数组 &二分&贪心)
题目描述 nodgd的粉丝太多了,每天都会有很多人排队要签名. 今天有n个人排队,每个人的身高都是一个整数,且互不相同.很不巧,nodgd今天去忙别的事情去了,就只好让这些粉丝们明天再来.同时nod ...
- 【洛谷】NOIP提高组模拟赛Day2【动态开节点/树状数组】【双头链表模拟】
U41571 Agent2 题目背景 炎炎夏日还没有过去,Agent们没有一个想出去外面搞事情的.每当ENLIGHTENED总部组织活动时,人人都说有空,结果到了活动日,却一个接着一个咕咕咕了.只有不 ...
- 【bzoj4548】小奇的糖果 STL-set+树状数组
题目描述 平面上有n个点,每个点有一种颜色.对于某一条线段,选择所有其上方或下方的点.求:在不包含所有颜色的点的前提下,选择的点数最多是多少.(本题中如果存在某颜色没有相应的点,那么选择任何线段都不算 ...
- 牛客小白月赛13-H(单调栈+树状数组)
题目链接:https://ac.nowcoder.com/acm/contest/549/H 题意:给一个柱状图,包括每个矩阵的宽度和高度,求能组成的最大矩阵的面积. 思路:显然最大矩阵的高一定为n个 ...
- 2019.01.21 bzoj2441: [中山市选2011]小W的问题(树状数组+权值线段树)
传送门 数据结构优化计数菜题. 题意简述:给nnn个点问有多少个www型. www型的定义: 由5个不同的点组成,满足x1<x2<x3<x4<x5,x3>x1>x2 ...
- 「模拟赛20180307」三元组 exclaim 枚举+树状数组
题目描述 给定 \(n,k\) ,求有多少个三元组 \((a,b,c)\) 满足 \(1≤a≤b≤c≤n\)且\(a + b^2 ≡ c^3\ (mod\ k)\). 输入 多组数据,第一行数据组数\ ...
- bzoj 4826: [Hnoi2017]影魔【单调栈+树状数组+扫描线】
参考:https://www.cnblogs.com/lcf-2000/p/6789680.html 这是一个相对码量少的做法,用到了区间修改区间查询的树状数组,详见:www.cnblogs.com/ ...
- 算法笔记求序列A每个元素左边比它小的数的个数(树状数组和离散化)
#include <iostream> #include <algorithm> #include <cstring> using namespace std ; ...
- BZOJ4237 稻草人(分治+树状数组+单调栈)
如果要询问的某个纵坐标为inf的点左边是否有点能与其构成所要求的矩形,只要用个单调栈就可以了.可以想到用分治来制造单调性. 按横坐标排序,每次考虑跨过分治中心的矩形.考虑右边的每个点能与左边的哪些点构 ...
随机推荐
- 前端 CSS 盒子模型 边框 border属性
边框 border:边框的意思,描述盒子的边框 边框有三个要素: 粗细 线性样式 颜色 border: solid border特性 如果颜色不写,默认是黑色.如果粗细不写,不显示边框.如果只写线性样 ...
- 复制/etc目录下所有以p开头,以非数字结尾的文件或目录到/tmp/mytest1目录中
cp -r /etc/p*[a-Z] /tmp/mytest1
- 第二周总结.Java
本学期开始学习Java课程了,首先我先说说学习Java的感觉吧,它不像C语言程序设计,但是又有语言开发的共同点.学Java语言重点是面向对象的程序设计,更加的适应生活需要和计算机开发的需要. 总的来讲 ...
- gRPC go安装教程
安装protobuf go get -u github.com/golang/protobuf/proto go get -u github.com/golang/protobuf/protoc-ge ...
- 2019 Multi-University Training Contest 2 - 1011 - Keen On Everything But Triangle - 线段树
http://acm.hdu.edu.cn/showproblem.php?pid=6601 首先要贪心地想,题目要最长的边长,那么要怎么构造呢?在一段连续的区间里面,一定是拿出最长的三根出来比,这样 ...
- 出现( linker command failed with exit code 1)错误总结(http://blog.csdn.net/hengshujiyi/article/details/21182813)
这种问题,通常出现在添加第三方库文件或者多人开发时. 这种问题一般是找不到文件而导致的链接错误. 我们可以从如下几个方面着手排查. 1.以如下错误为例,如果是多人开发,你同步完成后发现出现如下的错误. ...
- Linux学习--第五天--vim使用、rpm命令
vim使用 三种模式: 编辑模式 插入模式 命令模式 |命令|作用| |--|--| |a|在光标字符后插入| |A|在光标行尾插入| |i|在光标字符前插入| |I|在光标行首插入| |o|在光标下 ...
- CF1260C Infinite Fence 题解(扩欧)
题目地址 CF1260C 题目大意 现有\(10^{100}\)块木板需要涂漆,第x块如果是x是a的倍数,则涂一种颜色,是b的倍数,则涂另一种颜色.如果既是a又是b的倍数,那么两种颜色都可以涂:如果连 ...
- ztree 获取CheckBox选中节点时,不获取选中上级父节点
//将第三个参数改为false,表示不去勾选父节点下的所有子节点 zTreeObj.checkNode(node, true, false); setting.check.chkboxType = { ...
- mysql RIGHT JOIN关键字 语法
mysql RIGHT JOIN关键字 语法 作用:RIGHT JOIN 关键字会右表 (table_name2) 那里返回所有的行,即使在左表 (table_name1) 中没有匹配的行.惠州大理石 ...