Description

已知一个长度为n的序列a1,a2,...,an。

对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt(abs(i-j))

Input

第一行n,(1<=n<=500000)

下面每行一个整数,其中第i行是ai。(0<=ai<=1000000000)

Output

n行,第i行表示对于i,得到的p

Sample Input

6

5

3

2

4

2

4

Sample Output

2

3

5

3

5

4


决策单调性优化DP

。。。调了一晚上,都要自闭了


首先可以发现根号函数是一个增长越来越慢的函数

所以一个点如果不能对答案造成贡献,那么他永远都不能造成贡献了

然后就考虑怎么维护这个东西

首先正反跑两遍然后取max这个思路非常显然

现在可以考虑怎么维护单次的贡献

因为对于i,需要最大化

\(h_j - h_i + sqrt(i-j)\)

所以我们可以把原序列划分成一些区间

使得这些区间可以取到最大值

然后每次统计贡献直接在区间上查找就可以了

考虑维护一个队列来维护\([i,n]\)这个区间的所有最优区间

每个节点用三元组\([l,r,pos]\)表示

代表在\([l,r]\)这个区间里面pos可以贡献最大值

然后直接每次看一看如果当前新加入的节点是可以完全包含末尾区间,直接弹出,知道不能操作

这时如果序列为空直接加入\([i,n,i]\)

否则把最后一个区间划分成两个区间进行操作就可以了


注意统计贡献的时候参数顺序很重要


//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
//typename
typedef long long ll;
//convenient for
#define for_up(a, b, c) for (int a = b; a <= c; ++a)
#define for_down(a, b, c) for (int a = b; a >= c; --a)
#define for_vector(a, b) for (int a = 0; a < (signed)b.size(); ++a)
//inf of different typename
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
//fast read and write
template <typename T>
void Read(T &x) {
bool w = 1;x = 0;
char c = getchar();
while (!isdigit(c) && c != '-')c = getchar();
if (c == '-')w = 0, c = getchar();
while (isdigit(c)) {
x = (x<<1) + (x<<3) + c -'0';
c = getchar();
}
if (!w) x = -x;
}
template <typename T>
void Write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)Write(x / 10);
putchar(x % 10 + '0');
}
//----------------------------------------------
const int N = 500010;
const double eps = 1e-5;
int n, l, r;
int dp[N] = {0}, h[N];
struct Node {
int l, r, pos;
Node(){}
Node(int l, int r, int pos):l(l), r(r), pos(pos){}
}p[N];
double cal(int a, int b) { // 一定注意顺序 是统计 a覆盖b的最小高度
return (double)h[b] + sqrt(abs(a - b)) - (double)h[a];
}
int find(Node t, int x) {
int l = t.l, r = t.r, ans = 0;
while (l <= r) {
int mid = (l + r) >> 1;
if(cal(mid, t.pos) <= cal(mid, x)) r = mid - 1, ans = mid;
else l = mid + 1;
}
return ans;
}
void solve(bool typ) {
int l = 1, r = 0;
for_up(i, 1, n) {
if (l <= r && ++p[l].l > p[l].r) ++l;
if (l > r || cal(n, i) > cal(n, p[r].pos)) {
// p[r] 无论如何不会比i优 直接弹掉
while (l <= r && cal(p[r].l, p[r].pos) < cal(p[r].l, i)) --r;
int now = (l > r) ? i : find(p[r], i);
if (l <= r) p[r].r = now - 1;// 如果上一个区间存在 更新右端点
p[++r] = (Node){now, n, i};
}
int id = typ ? n - i + 1 : i;
dp[id] = max(dp[id], (int)ceil(cal(i, p[l].pos)));
}
}
int main() {
Read(n);
for_up(i, 1, n) Read(h[i]);
solve(0);
reverse(h + 1, h + n + 1);
solve(1);
for_up(i, 1, n) {
Write(dp[i]);
putchar('\n');
}
return 0;
}

BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】的更多相关文章

  1. P3515 [POI2011]Lightning Conductor[决策单调性优化]

    给定一序列,求对于每一个$a_i$的最小非负整数$p_i$,使得$\forall j \neq i $有$ p_i>=a_j-a_i+ \sqrt{|i-j|}$. 绝对值很烦 ,先分左右情况单 ...

  2. 【BZOJ2216】[Poi2011]Lightning Conductor 决策单调性

    [BZOJ2216][Poi2011]Lightning Conductor Description 已知一个长度为n的序列a1,a2,...,an.对于每个1<=i<=n,找到最小的非负 ...

  3. LOJ2074/2157 JSOI2016/POI2011 Lightning Conductor 决策单调性DP

    传送门 我们相当于要求出\(f_i = \max\limits_{j=1}^{n} (a_j + \sqrt{|i-j|})\).这个绝对值太烦人了,考虑对于\(i>j\)和\(i<j\) ...

  4. Lightning Conductor 洛谷P3515 决策单调性优化DP

    遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...

  5. 决策单调性优化dp 专题练习

    决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...

  6. CF868F Yet Another Minimization Problem 分治决策单调性优化DP

    题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...

  7. 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)

    传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...

  8. [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)

    第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...

  9. BZOJ_2216_[Poi2011]Lightning Conductor_决策单调性

    BZOJ_2216_[Poi2011]Lightning Conductor_决策单调性 Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n, ...

随机推荐

  1. [异常记录(二)] 验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。

    错误提示: 验证视图状态 MAC 失败.如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法.不能在群集中使用 Au ...

  2. Asp.Net将Session保存在数据库中

    1.由于项目dll文件变动比较频繁,而保存登陆的状态又保存在Session中,所以导致用户经常无故掉线.(dll变动的时候导致Session丢失) 2.有一种方法可以长期保存session,那就是se ...

  3. rest 学习总结(最近不间断更新)

    一.rest 简单介绍 1.http://www.zhihu.com/question/27785028 2.http://www.cnblogs.com/549294286/p/3524064.ht ...

  4. vue-router之学习笔记

    用 Vue.js + vue-router 创建单页应用,是非常简单的.使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 vue-router 添加进来,我们需要做的是,将组件( ...

  5. Spring Boot技术栈博客笔记(1)

    要实现的核心功能 用户管理 安全设置 博客管理 评论管理 点赞管理 分类管理 标签管理 首页搜索 核心技术 数据存储 随着spring3发布以来,spring团队减少使用xml配置的使用,采用大量约定 ...

  6. 如何使用POST 方法调用服务

    一.WCF REST专用POST方法 1.1.        建立WCF REST 方法 [ServiceContract] public interface IBookingBizService { ...

  7. 何时使用img标签,何时使用background-image背景图像

    在什么情况下更适合使用HTML IMG标签来显示一个图像,而不是一个CSS有背景图像,反之亦然? 如下场景使用img标签比较合适: 1.如果图像是等内容的一部分或图表或人(真正的人,而不是股票图人), ...

  8. C# 终于写完了简单的ORM

    实现单表 增 .删. 改 .查 使用接口定义表实体数据.实体对象动态创建,使用 Email 进行数据读取. 存储过程调用示例

  9. Python 常用 PEP8 编码规范

    Python 常用 PEP8 编码规范 代码布局 缩进 每级缩进用4个空格. 括号中使用垂直隐式缩进或使用悬挂缩进. EXAMPLE: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 ...

  10. 关于js中的原型链的理解

    我们知道无论什么时候只要创建了一个函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象,默认情况下所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包 ...