#三分,分治,计算几何,prim#JZOJ 3860 地壳运动
题目
\(q\)组询问查询最小生成树,边权为\(u*k1+v*k2\)(\(k1,k2\)每次询问都不同)
\(n\leq 35,m\leq 25000,q\leq 200000\)
分析
纯\(\text{Prim}\)爽赚60
按照题解的旨意,可以建立一个下凸壳,边界是\((1,0),(0,1)\)这是系数,然后要用这个系数跑最小生成树得到\((x=\sum u,y=\sum v)\)
要找到一个最远的点使得它在凸壳上,然而我太菜了不知道怎样推出来\((abs(r.y-l.y),abs(r.x-l.x))\)
然后不断分治下去,既然是凸壳,那么任意三点不能在同一条直线上,也就是斜率相等就没有了,既然是一个下凸壳,就是一个单谷函数可以三分求解
代码
#include <cstdio>
#include <cctype>
#include <cmath>
#define rr register
using namespace std;
struct Sline{double k,b,x,y;}sl[371],head,tail; bool v[37];
int cost[37][37],X[25011],n,m,Q,Y[25011],U[25011],V[25011],Min[37],tot;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline double min(double a,double b){return a<b?a:b;}
inline double answ(Sline Sl,int p){return U[p]*Sl.k+V[p]*Sl.b;}
inline void prim(Sline &Sl){
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n;++j) cost[i][j]=0;
for (rr int i=1;i<=n;++i) cost[i][i]=1;
for (rr int i=2;i<=m+1;++i){
if (answ(Sl,i)<answ(Sl,cost[X[i]][Y[i]]))
cost[X[i]][Y[i]]=cost[Y[i]][X[i]]=i;
}
for (rr int i=1;i<=n;++i) v[i]=(i==1),Min[i]=cost[1][i];
for (rr int i=1;i<n;++i){
rr int minp=0;
for (rr int j=1;j<=n;++j)
if (!v[j]&&answ(Sl,Min[minp])>answ(Sl,Min[j])) minp=j;
Sl.x+=U[Min[minp]],Sl.y+=V[Min[minp]],v[minp]=1;
for (rr int j=1;j<=n;++j)
if (!v[j]&&answ(Sl,Min[j])>answ(Sl,cost[minp][j])) Min[j]=cost[minp][j];
}
}
inline void divi(Sline l,Sline r){
rr Sline mid=(Sline){fabs(r.y-l.y),fabs(r.x-l.x),0,0}; prim(mid);
if (l.y==mid.y||mid.y==r.y||(l.x-mid.x)/(l.y-mid.y)==(l.x-r.x)/(l.y-r.y)) return;
divi(l,mid),sl[++tot]=mid,divi(mid,r);
}
inline double calc(double k1,double k2,int p){return sl[p].x*k1+sl[p].y*k2;}
signed main(){
n=iut(),m=iut(),Q=iut(),U[0]=V[0]=1e7;
for (rr int i=2;i<=m+1;++i) X[i]=iut(),Y[i]=iut(),U[i]=iut(),V[i]=iut();
head.k=tail.b=1,prim(head),prim(tail),sl[++tot]=head,divi(head,tail),sl[++tot]=tail;
for (rr int i=1;i<=Q;++i){
rr double k1,k2,ans=1e18; rr int l=1,r=tot;
scanf("%lf%lf",&k1,&k2);
while (l+2<r){
rr int k=(r-l+1)/3,lmid=l+k,rmid=r-k;
if (calc(k1,k2,lmid)<calc(k1,k2,rmid)) r=rmid; else l=lmid;
}
for (rr int i=l;i<=r;++i) ans=min(ans,calc(k1,k2,i));
printf("%.3lf\n",ans);
}
return 0;
}
#三分,分治,计算几何,prim#JZOJ 3860 地壳运动的更多相关文章
- Codeforces 8D Two Friends 三分+二分+计算几何
题目链接:点击打开链接 题意:点击打开链接 三分house到shop的距离,二分这条斜边到cinema的距离 #include<stdio.h> #include<string.h& ...
- 分治 - 计算几何 - BZOJ2458,[BeiJing2011]最小三角形
http://www.lydsy.com/JudgeOnline/problem.php?id=2458 [BeiJing2011]最小三角形 描述 Frisk现在遇到了一个有趣的问题. 平面上有N个 ...
- 总结(2019CSP之后),含题解
从\(\mathcal{CSP}\) 爆炸 到现在,已经有\(3\)个月了.这三个月间,我--这个小蒟蒻又接触了许多听不懂的东西 \(\mathcal{No.}1\) 字符串\(\mathcal{ha ...
- NC20276 [SCOI2010]传送带
NC20276 [SCOI2010]传送带 题目 题目描述 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD ...
- 计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点
平面最近点对,即平面中距离最近的两点 分治算法: int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对 { double ans; //an ...
- [BZOJ4311]向量(凸包+三分+线段树分治)
可以发现答案一定在所有向量终点形成的上凸壳上,于是在上凸壳上三分即可. 对于删除操作,相当于每个向量有一个作用区间,线段树分治即可.$O(n\log^2 n)$ 同时可以发现,当询问按斜率排序后,每个 ...
- BZOJ4311 向量(线段树分治+三分)
由点积的几何意义(即投影)可以发现答案一定在凸壳上,并且投影的变化是一个单峰函数,可以三分.现在需要处理的只有删除操作,线段树分治即可. #include<iostream> #inclu ...
- 斜率优化建图学习笔记 & JZOJ 地壳运动题解
本章学习斜率优化建图 请放心食用 引言 最小生成树(\(mst\)) (\(Algorithm: \text {Prim or Kruskal}\)) 从裸题到一丁点技巧,再到丧心病狂的神仙题 原始时 ...
- hdu 4717 The Moving Points(三分+计算几何)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4717 说明下为啥满足三分: 设y=f(x) (x>0)表示任意两个点的距离随时间x的增长,距离y ...
- Codeforces Gym100543B 计算几何 凸包 线段树 二分/三分 卡常
原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100543B.html 题目传送门 - CF-Gym100543B 题意 给定一个折线图,对于每一条 ...
随机推荐
- Docker实践之07-数据管理
目录 一.数据卷概述 二.创建数据卷 三.查看数据卷 四.挂载数据卷 五.删除数据卷 六.挂载主机目录或文件 七.挂载数据卷与主机目录/文件的比较 一.数据卷概述 数据卷是一个可供一个或多个容器使用的 ...
- 文件IO操作开发笔记(二):使用Cpp的ofstream对磁盘文件存储进行性能测试以及测试工具
前言 在做到个别项目对日志要求较高,要求并行写入的数据较多,尽管写入数据的线程放在子线程,仍然会造成界面程序的假死(实际上Qt还是在跑,只是磁盘消耗超过瓶颈,造成假死(注意:控制台还能看到打印输出 ...
- re.sub参数之回调函数
from calendar import month_abbr import re def change_date(m): mon_name = month_abbr[int(m.group(1))] ...
- 深入理解maven及应用
在项目里用了快一年的maven了,最近突然发现maven项目在eclipse中build时非常慢,因为经常用clean install命令来build项目,也没有管那么多,但最近实在受不了乌龟一样的b ...
- 【转载】很遗憾,没有一篇文章能讲清楚ZooKeeper
作为分布式系统解决方案的 ZooKeeper,被广泛应用于多个分布式场景.例如:数据发布/订阅,负载均衡,命名服务,集群管理等等. 因此,ZooKeeper 在分布式系统中扮演着重要的角色,今天通过一 ...
- C++11新特性的一些用法举例①
//字符串字面量/*常用:1.原始字符串字面量 --- 括号内保持原样输出 --- 没有转义字符,如\n不再是换行,而是直接输出字面量\nR"(str)"; 实例: R" ...
- 从源码看webpack3打包流程
在javascript刚刚流行时,前端项目通常比较简单,不需要考虑项目的开发效率.性能和扩展性等. 随着前端项目越来越复杂,需要更正式的软件开发实践,比如单元测试(unit testing).代码检查 ...
- 【预训练语言模型】BERT原理解析、常见问题和微调实战
一.BERT原理 1.概述 背景:通过在大规模语料上预训练语言模型,可以显著提高其在NLP下游任务的表现. 动机:限制模型潜力的主要原因在于现有模型使用的都是单向的语言模型 ...
- C++类的访问权限
首先明确一个类的用户有三种: 一类用户:类的成员和友元 二类用户:子类的成员及子类的友元 三类用户:外部的用户代码(通过类的对象或指针) 一个类有三种成员 private:只有一类用户可以访问priv ...
- UE虚幻引擎:生成云平台指定路径下的EXE文件
市面上大量优秀的游戏都是基于UE制作的,UE虚幻引擎制作的作品可以在windows.mac.linux以及ps4.x-boxone.ios.android甚至是html5等平台上运行.本文介绍了UE虚 ...