洛谷P2497:基站建设(splay、斜率优化)

所谓splay斜率优化dp,就是利用splay和斜率对dp进行优化

(逃)

解析

在斜优的时候,有时我们会发现我们插入的点的横坐标并不单调
这个时候我们就无法利用单调队列维护凸包了
这时,我们就要请出今天的主角:splay

插点

splay斜优最容易错的一个地方
我们维护一个以结点横坐标作为关键值的splay
结点记录第信息有:左右儿子、父亲、xy坐标、分别与左右两边第一个结点的斜率
注意这个第一个结点不一定是左右儿子!
特别的,没有儿子时赋值成正(右)负(左)无穷

step1

首先,让我们把结点按照splay的常规操作塞进去

if(!rt){rt=New(x,y,id,0);lk[rt]=-2e18;rk[rt]=2e18;return;}int now=rt;while(1){if(tr[now][x>dx[now]]) now=tr[now][x>dx[now]];else{tr[now][x>dx[now]]=New(x,y,id,now);splay(tot);break;}}

step2

但是这样,可能凸包的性质会被打破
我们需要继续维护凸包的性质
首先,这个结点可能会是两边的点变成需要去掉的上凸点
下面以左侧为例

加入一个x点时:
请添加图片描述
显然,3点和4点应该舍去
原本的点集满足凸包性质的前提下
我们其实只需要找到左边第一个满足 lki<slope(i,x)lk_i<slope(i,x)lki<slope(i,x)的点 (在本图中就是2)
我们可以在splay上通过类似二分的方法来实现这个操作

inline int pre(){int now=tr[rt][0],res=0;while(now){if(lk[now]<slope(now,rt)+eps){res=now;now=tr[now][1];}else now=tr[now][0];}return res;
}

找到这个pre之后,把pre和当前点之间的点全部删去即可

if(tr[now][0]){int o=pre();//printf("?:\n");splay(o,now);tr[o][1]=0;lk[now]=rk[o]=slope(o,now);}

记得更新斜率!!!

step3

考虑到当前点本身可能就是上凸点
我们特判一下如果是直接把它删掉即可
特判的依据就是lkx>rkxlk_x>rk_xlkx>rkx
注意这个特判必须在step2之后!!
为什么?因为x的lk和rk都是在step2求的…

if(lk[now]>rk[now]+eps){int ls=tr[now][0],rs=tr[now][1];f[ls]=0;rt=ls;tr[ls][1]=rs;f[rs]=ls;lk[rs]=rk[ls]=slope(ls,rs);}

查询

对于一个斜率k
找到 lki≤k≤rkilk_i \leq k \leq rk_ilkikrki 的位置即可
相对比较简单

if(lk[now]>rk[now]+eps){int ls=tr[now][0],rs=tr[now][1];f[ls]=0;rt=ls;tr[ls][1]=rs;f[rs]=ls;lk[rs]=rk[ls]=slope(ls,rs);}

update

本题中的横坐标两两不同,但有些题并非如此,需要特判横坐标相同的情况!
具体而言,只需要在插点的地方这么写:

	int x;//这里维护的上凸包if(!now) rt=New(xx,yy,0),x=rt;else{while(1){if(abs(dx[now]-xx)<eps){if(dy[now]<yy) return;else{dy[now]=yy;splay(now);x=now;break;}}if(tr[now][xx>dx[now]]) now=tr[now][xx>dx[now]];else{tr[now][xx>dx[now]]=New(xx,yy,now);splay(tot);x=tot;break;}}}.......

代码

主函数就变得非常easy!

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define debug(a) fprintf(stderr,a)
const int N=5e5+1000;
const int M=3e6+100;
const int mod=998244353;
const double eps=1e-10;
inline ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;
}
int n,m;
int tr[N][2],f[N],idx[N],rt,tot;
double lk[N],rk[N],dx[N],dy[N];
inline int New(double x,double y,int id,int fa){++tot;tr[tot][0]=tr[tot][1]=0;f[tot]=fa;dx[tot]=x;dy[tot]=y;idx[tot]=id;return tot;
}
inline bool which(int x){return tr[f[x]][1]==x;}
inline void rotate(int x){int fa=f[x],gfa=f[fa];int d=which(x),son=tr[x][d^1];f[x]=gfa;if(gfa) tr[gfa][which(fa)]=x;f[fa]=x;tr[x][d^1]=fa;if(son) f[son]=fa;tr[fa][d]=son;return;
}
inline void splay(int x,int goal=0){//printf("x=%d goal=%d fa=%d\n",x,goal,f[x]);for(int fa;(fa=f[x])!=goal;rotate(x)){if(f[fa]!=goal) which(fa)==which(x)?rotate(fa):rotate(x);}if(!goal) rt=x;return;
}
#define slope(u,v) ((dy[v]-dy[u])/(dx[v]-dx[u]))
inline int pre(){int now=tr[rt][0],res=0;while(now){if(lk[now]<slope(now,rt)+eps){res=now;now=tr[now][1];}else now=tr[now][0];}return res;
}
inline int nxt(){int now=tr[rt][1],res=0;while(now){if(rk[now]+eps>slope(rt,now)){res=now;now=tr[now][0];}else now=tr[now][1];}return res;
}
inline void ins(double x,double y,int id){if(!rt){rt=New(x,y,id,0);lk[rt]=-2e18;rk[rt]=2e18;return;}int now=rt;while(1){if(tr[now][x>dx[now]]) now=tr[now][x>dx[now]];else{tr[now][x>dx[now]]=New(x,y,id,now);splay(tot);break;}}//for(int i=1;i<=tot;i++) printf("i=%d ls=%d rs=%d (%.3lf %.3lf)\n",i,tr[i][0],tr[i][1],dx[i],dy[i]);now=rt;if(tr[now][0]){int o=pre();//printf("?:\n");splay(o,now);tr[o][1]=0;lk[now]=rk[o]=slope(o,now);}else lk[now]=-2e18;if(tr[now][1]){int o=nxt();splay(o,now);tr[o][0]=0;rk[now]=lk[o]=slope(o,now);}else rk[now]=2e18;if(lk[now]>rk[now]+eps){int ls=tr[now][0],rs=tr[now][1];f[ls]=0;rt=ls;tr[ls][1]=rs;f[rs]=ls;lk[rs]=rk[ls]=slope(ls,rs);}return;
}
int query(double k){int now=rt;while(1){if(!now) return 0;//printf("now=%d lk=%.3lf rk=%.3lf (%.3lf %.3lf)\n",now,lk[now],rk[now],dx[now],dy[now]);if(lk[now]-eps<=k&&k<=rk[now]+eps) return idx[now];else if(lk[now]+eps>k) now=tr[now][0];else now=tr[now][1];}
}
double ans=2e18;
int v[N];
ll x[N];
double dp[N],r[N];
#define X(o) (-1.0/(2.0*sqrt(r[o])))
#define Y(o) (dp[o]-1.0*x[o]/(2*sqrt(r[o])))
int main() {
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();m=read();for(int i=1;i<=n;i++){x[i]=read();r[i]=read();v[i]=read();}dp[1]=v[1];ins(X(1),Y(1),1);//printf("  i=%d dp=%.3lf (%.3lf,%.3lf)\n\n",1,dp[1],X(1),Y(1));for(int i=2;i<=n;i++){//printf("i=%d\n",i);int j=query(x[i]);//printf("  ok\n");dp[i]=dp[j]+1.0*(x[i]-x[j])/(2*sqrt(r[j]))+v[i];//printf("  j=%d i=%d dp=%.3lf (%.3lf,%.3lf)\n\n",j,i,dp[i],X(i),Y(i));ins(X(i),Y(i),i);if(x[i]+r[i]>=m) ans=min(ans,dp[i]);}//printf("ceck:%3lf\n",slope(1,2));printf("%.3lf\n",ans);return 0;
}
/*
3 1
3 1 33 2
1 1 2
3 1 3
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317726.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MediatR 知多少

引言首先不用查字典了&#xff0c;词典查无此词。猜测是作者笔误将Mediator写成MediatR了。废话少说&#xff0c;转入正题。先来简单了解下这个开源项目MediatR&#xff08;作者Jimmy Bogard&#xff0c;也是开源项目AutoMapper的创建者&#xff0c;在此表示膜拜&#xff09;&a…

网络分析(带权并查集)

网络分析 题意&#xff1a; 有n个节点&#xff0c;一开始彼此独立&#xff0c;有两个操作&#xff0c;第一个操作时是连接两个节点&#xff0c;第二个操作是对一个节点x&#xff0c;&#xff08;在进行第二个操作时&#xff0c;与该点相连的点也会x&#xff09; 问每个节点的…

良心发现,时隔一年再回首莫比乌斯反演(公式性质证明+题目练习)

文章目录莫比乌斯反演引入公式性质模板公式证明莫比乌斯函数前缀和题目练习完全平方数[HAOI2011]ProblembYY的GCD[SDOI2014]数表[国家集训队]Crash的数字表格/JZPTAB[SDOI2015]约数个数和寒假疫情期间跟着lmm学了一遍&#xff0c;完全是懵逼到底状态&#xff0c;以至于后面考到…

平面切分

平面切分 问题描述 题解&#xff1a; 我对这种题极其非常不擅长。。。 另外吐槽为什么acwing的数据卡的这么死&#xff0c;蓝桥杯官网数据那么水 其实题目很简单&#xff0c;如果只有一个直线&#xff0c;那么就是两部分&#xff0c;如果是两个直线&#xff0c;这两个直线不相…

新起点!新征程!微软技术俱乐部(苏州)成立大会暨微软技术交流会

2019年1月19日&#xff0c;苏州微软将举办苏州史上最盛大的开发者聚会&#xff0c;微软技术俱乐部成立大会暨微软技术交流会。超越苹果&#xff0c;登顶世界市值第一&#xff01;云与AI两大技术支柱支撑起的微软帝国&#xff0c;正向万亿美元俱乐部挺进&#xff01;微软的改变我…

跨平台、跨语言应用开发工具,Elements 介绍

目录1&#xff0c;Elements 介绍2&#xff0c;Elements 版本3&#xff0c;Elements 能干嘛4&#xff0c;Elements IDES5&#xff0c;Elements 工具1&#xff0c;Elements 介绍RemObjects Elements&#xff0c;是多平台移动项目开发工具&#xff0c;是一款可以帮助开发人员在 不…

后缀自动机(SAM)构造实现过程演示+习题集锦

文章目录后缀自动机算法实现过程模板习题洛谷后缀自动机模板题品酒大会[HEOI2015]最短不公共子串字符串蒟蒻写这篇blogblogblog主要是存一下&#xff0c;后缀自动机的详细搭建过程&#xff0c;方便以后复习 具体的某些证明&#xff0c;为什么这么做&#xff0c;正确性劈里啪啦一…

使用logdashboard进行可视化的日志追踪

本文源码在Github可以找到下载LogDashboard如果你还不了解LogDashboard请看这里。 LogDashboard 1.1版本支持请求追踪,虽然目前版本还没有发布。不过这个功能可以先睹为快效果图下载项目首先我们可以在 https://github.com/liangshiw/LogDashboard/tree/master/samples/Request…

ML.NET 0.9特性简介

ML.NET 0.9已于上周发布&#xff0c;距离上次0.8版本的发布只有一个多月&#xff0c;此次增加的新特性主要包括特征贡献计算&#xff0c;模型可解释性增强&#xff0c;ONNX转换对GPU的支持&#xff0c;Visual Studio ML.NET项目模板预览&#xff0c;以及API改进。特征贡献计算特…

[学习笔记] 初次见面,请多关照 (公式推导+题集)——杜教筛

筛积性函数的前缀和常见积性函数公式推导狄利克雷卷积杜教筛实现常见卷积习题集Sum神犇和蒟蒻简单的数学题常见积性函数 μ\muμφφφd(n)d(n)d(n)&#xff1a;nnn的约数个数σ(n)σ(n)σ(n)&#xff1a;nnn的约数和ϵ(n)ϵ(n)ϵ(n)&#xff1a;单位元函数&#xff0c;e(n)[n1…

AOP 还在配置吗改用打标签模式吧!

为什么我喜欢打标签来配置AOP1. 配置多很混乱&#xff0c;代码里面很难分辨出来哪些是AOP容器(比如属性注入)2. 对于代码生成器生成的代码里面还需要手动加到配置里面3. 连java spring现在都是清一色的注解来代替xml&#xff0c;这个就是趋势所在我基于Autofac开发了一个基于标…

DZY Loves Math IV(杜教筛)

文章目录titlesolutioncodetitle solution 这道题是多么的妙啊&#xff0c;完全不是我能推出来的式子呢&#xff01; 观察数据范围&#xff0c;有点奇怪欸&#xff0c;在暗示我&#xff1f;&#xff1f; 考虑暴力枚举nnn S(n,m)∑i1mφ(ni)S(n,m)\sum_{i1}^mφ(n\times i)S…

codeforces:CF1604 总结

前言 solve&#xff1a;4 rank&#xff1a;48&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 这排名我不理解了 solve4真真不算多啊… 而且前四题感觉也不算太难… 仔细看了看榜 哦… 因为这次…

IdentityServer4直播

大家好&#xff0c;很久没有更新公众号&#xff0c;让各位久等了&#xff0c;主要是最近出除了工作之外&#xff0c;一直私下在学习和研究IdentityServer4&#xff0c;后续会腾出一部分时间陆续更新公众号。对于IdentityServer4(简称IDS)&#xff0c;网上的资料少之可怜&#x…

.NET Core 3.0:System.Data的变化

System.Data虽然不引人关注&#xff0c;但在.NET中&#xff0c;System.Data对于各种关系数据库的连接是非常重要的。System.Data也被称为ADO.NET&#xff0c;其前身是ActiveX Data Objects。System.Data提供了通过的框架&#xff0c;在她的基础上.NET数据驱动应用可以被构建。这…

蓝桥杯国赛 皮亚诺曲线距离

参考博客 题意&#xff1a; 题解&#xff1a; 这个很恶魔 本质好说就是找规律&#xff0c;但是贼难写。。 找了篇题解&#xff0c;做法就是大化小&#xff0c;将大阶化为成小阶&#xff0c;计算出离远点的距离。。。我感觉我是写不出来。。 挺秒的&#xff0c;要推公式估计要…

将 Visual Studio 的代码片段导出到 VS Code

导语和原文作者一样&#xff0c;水弟我现在也是使用 VS Code 和 Rider 作为主力开发工具&#xff0c;尤其是 VS Code 可以跨平台&#xff0c;又有丰富的插件支持和多种编程语言支持。当我从 VS 转移到以 VS Code 的开发过程中&#xff0c;遇到的最大问题就是代码提示的不完善&a…

如何基于 Kubernetes 构建完整的 DevOps 流水线

前言关于 DevOps 是一个很大的话题&#xff0c;它可能既涉及到公司的技术文化构建&#xff0c;也包括开发者技术能力的支持&#xff0c;这次技术干货分享主要是侧重于技术方面&#xff0c;就是如何用 Kubernetes 来服务好 DevOps 的流水线。本文从 4 个方面介绍&#xff1a;什么…

[SNOI2017]遗失的答案 (FWT)

description 小皮球在计算出答案之后&#xff0c;买了一堆皮肤&#xff0c;他心里很开心&#xff0c;但是一不小心&#xff0c;就忘记自己买了哪些皮肤了。 ||| 万幸的是&#xff0c;他还记得他把所有皮肤按照 1∼N 来编号&#xff0c;他买来的那些皮肤的编号&#xff08;他至…

Abp中使用可视化的日志面板

如果你还不了解LogDashboard请看这里 使用logdashboard查看可视化日志。ABP的相关知识不做介绍如果有需要请阅读ABP官方文档ABP是Net下非常优秀的开发框架,在中国很多的项目都正在使用它。现在我们可以使用LogDashboard增强在使用ABP开发中的查看日志能力。下载ABP模板项目打开…