当前位置: 首页 > news >正文

BZOJ2216: [Poi2011]Lightning Conductor(DP 决策单调性)

题意

题目链接

Sol

很nice的决策单调性题目

首先把给出的式子移项,我们要求的$P_i = max(a_j + \sqrt{|i - j|}) - a_i$。

按套路把绝对值拆掉,$p_i = max(max_{j = 1}^i (a_j = \sqrt{i - j}), max_{j = i + 1}^n (a_j + \sqrt{j - i})) - a_i$

对于后面的一段,我们把序列翻转之后和前一段是等价的。

也就是说,我们现在只需要找到$P_i = max_{j = 1}^i (a_j + \sqrt{i - j})$

考虑到式子中只有一个max函数,那这玩意儿应该是有决策单调性的

直接设$f_j = a_j + \sqrt{i - j}, i \geqslant j$,其中$i$是自变量

观察这个函数,应该是一个在$[j, INF]$内有定义,过点$(j, a[j])$的函数,且增速与函数$g_i = \sqrt{i}$相同

我们需要做的,就是对每个$i$,找到最大的$f_j$

考虑到$g_i$增长速度会越来越慢,所以一个函数增长到一定程度后可能会被另一个函数取代

直接用单调队列维护,设$K_{i, j}$表示$f_i, f_j$的交点,$h, t$分别表示队首/尾,

当新加入一个元素$i$的时候,显然,若$K_{t -1, t} > K_{t - 1, i}$,那么$t$这个函数是没用的、

当$K_{h, h+1} < i$的时候,弹出队首

就是最后输出答案的时候有点“卡精度”,真恶心

经验:

以后看到$f_i = max(f_j) + g$的式子一定要往单调性上想,如果单调性不是很显然的话可以用换元法设函数找单调性

另外绝对值拆开算一般会好算一些

#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
const int MAXN = 1e6 + 10, INF = 1e9 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, a[MAXN], q[MAXN], Cro[MAXN];
double P[MAXN], sqr[MAXN];
double calc(int j, int i) {
    return a[j] + sqr[i - j];
}
int K(int x, int y) {
    int l = max(x, y), r = N, ans = N + 1;
    while(l <= r) {
        int mid = l + r >> 1;
        if(calc(x, mid) >= calc(y, mid)) l = mid + 1;
        else r = mid - 1, ans = mid;
    }
    return ans;
}
void solve() {
    int h = 1, t = 0;
    for(int i = 1; i <= N; i++) {
        while(h < t && K(q[t - 1], q[t]) >= K(q[t], i)) t--;
        q[++t] = i;
        while(h < t && K(q[h], q[h + 1]) <= i) h++;
        P[i] = max(P[i], calc(q[h], i));
    }
}
main() {
    N = read();
    for(int i = 1; i <= N; i++) a[i] = read(), sqr[i] = sqrt(i);
    solve();
    reverse(a + 1, a + N + 1);
    reverse(P + 1, P + N + 1);
    solve();
    for(int i = N; i >= 1; i--)
        printf("%d\n", max(0, (int)ceil(P[i]) - a[i]));
    return 0;
}

 

相关文章:

  • 递增链表的插入
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • Linux 环境变量的配置解决(-bash: jps: command not found)问题
  • Tomcat学习—Tomcat的简介和目录以及配置文件介绍(Windows环境)
  • Kafka简介
  • Jvm(49),指令集----异常处理指令
  • centos7设置开机启动
  • RedHat已更改其开源许可规则
  • C/C++——二维数组与指针、指针数组、数组指针(行指针)、二级指针的用法...
  • 程序员的迷茫期
  • Java集合源码学习(1)接口
  • 微信小程序【树形视图】demo
  • 使用JTAG调试器和Freemaster 2.0 进行powerpc架构的mpc5XXX系列的调试
  • EM算法随记
  • Vue 字段验证 八
  • [deviceone开发]-do_Webview的基本示例
  • Angular6错误 Service: No provider for Renderer2
  • gitlab-ci配置详解(一)
  • HTTP--网络协议分层,http历史(二)
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • MQ框架的比较
  • MySQL数据库运维之数据恢复
  • 大整数乘法-表格法
  • 浮动相关
  • 关于extract.autodesk.io的一些说明
  • 解析 Webpack中import、require、按需加载的执行过程
  • 前嗅ForeSpider中数据浏览界面介绍
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 怎么将电脑中的声音录制成WAV格式
  • 从如何停掉 Promise 链说起
  • 正则表达式-基础知识Review
  • ​queue --- 一个同步的队列类​
  • #NOIP 2014# day.2 T2 寻找道路
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (二)pulsar安装在独立的docker中,python测试
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • .apk文件,IIS不支持下载解决
  • .net反混淆脱壳工具de4dot的使用
  • .net下的富文本编辑器FCKeditor的配置方法
  • []FET-430SIM508 研究日志 11.3.31
  • [2010-8-30]
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [BZOJ 3282] Tree 【LCT】
  • [CISCN2019 华北赛区 Day1 Web2]ikun
  • [CUDA手搓]从零开始用C++ CUDA搭建一个卷积神经网络(LeNet),了解神经网络各个层背后算法原理
  • [ESP32 IDF]web server
  • [E链表] lc83. 删除排序链表中的重复元素(单链表+模拟)
  • [HCIE] IPSec-VPN (手工模式)
  • [hive] posexplode函数
  • [iOS开发]iOS中TabBar中间按钮凸起的实现
  • [J2ME]如何替换Google Map静态地图自带的Marker
  • [javaSE] 看知乎学习工厂模式
  • [Linux] day07——查看及过滤文本
  • [Linux] MySQL数据库之索引
  • [MySQL FAQ]系列 -- 账号密码包含反斜线时怎么办