首页 > 其他分享 >SDU Open 2023-H、几何、积分、单调栈维护上凸壳

SDU Open 2023-H、几何、积分、单调栈维护上凸壳

时间:2023-10-06 19:56:48浏览次数:57  
标签:SDU ld ll pt sz rep 2023 凸壳 tc

SDU Open 2023-H、几何、积分、单调栈维护上凸壳

题目:https://codeforces.com/gym/104324/problem/H

题意:有 \(n\) 个信号基站,你在边玩手机边走路,手机会自动连接到最近的基站。单位时间花费的流量是到基站距离的平方,现在从起点沿着直线走到终点,并且走的都是横平竖直的直线,单位时间移动单位距离,问最后花费了多少流量。

$ 1\leq n\leq 2000,1\leq m\leq 500$.


题解:

首先对走的每个折线段(至多 \(500\) 个)单独考虑流量花费,更进一步只考虑横着走的(把 \((x,y)\) 交换就可以做另一半),如此一来,考虑从某个 \((a_t ,b)\to (a_{t+1},b)\) 的折线段,这个过程中,只有 \(a\) 在动,中间每个基站 \((x_i,y_i)\) 到我的距离平方是:

\[(x_i-a)^2+(y_i-b)^2=a^2-2ax_i+x_i^2 +(y_i-b)^2=-2ax_i+\big(x_i^2+a^2+(y_i-b)^2\big) \]

后半部分除了 \(a^2\) 都是常数,而当我们对多个基站进行比较的时候,所有的 \(a^2\) 都是一样的,因此也可以直接忽略,这样一来在路径上每个位置,就只关心 \(-2ax_i +(x_i^2 +(y_i-b)^2)\) 最小的是哪个基站。这是关于 \(a\) 的一次函数!(记住,我们的自变量是 \(a\) )

因此把 \(-2x_i\) 看成斜率,$x_i^2 +(y_i-b)^2 $ 看成截距,就转化成单调栈维护上凸壳了。

实现的时候需要注意,如果两条直线的交点在区间外(即 \([\min(a_t,a_{t+1}),\max(a_t,a_{t+1})]\) 的话需要弹掉),以及可以把第 \(0\) 条直线设成左端点,这样一来第一条直线其交点横坐标就直接是左端点。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef long double ld;
const int N=2005;
const int M=505;
struct point{int x,y;}pt[N];
struct line{
	ll a,b,idx;
	line(ll a=0,ll b=0,int idx=0):a(a),b(b),idx(idx){}
	bool operator <(line rhs){return a>rhs.a;}
	ld calc(ld x){return a*x+b;}
}l[N],stk[N];

ld get(line L1,line L2){return ((ld)(L2.b-L1.b))/(L1.a-L2.a);}
int n,m,sz;
ld ans,x[N];
int a[M],b[M];

ld f(ld x,ll b,ll c){return x*x*x/3+x*x*b/2+x*c;}
ld INT(ld l,ld r,ll b,ll c){return f(r,b,c)-f(l,b,c);}
void work(){
	rep(tc,1,m-1)if(b[tc]==b[tc+1]){
		sz=0;
		int mi=min(a[tc],a[tc+1]),mx=max(a[tc],a[tc+1]);
		rep(i,1,n){
			ll A=-2*pt[i].x,B=pt[i].x*pt[i].x+(pt[i].y-b[tc])*(pt[i].y-b[tc]);//1e8+1e8
			l[i]=line(A,B,i);
		}
		sort(l+1,l+n+1);

		x[0]=mi;
		rep(i,1,n){//单调栈维护上凸壳,x[i]表示第i条直线和第i+1条直线的交点的横坐标,特别地[min,max]两端要放两条垂直的直线卡住
			while(sz&&stk[sz].calc(x[sz-1])>=l[i].calc(x[sz-1]))sz--;
			stk[++sz]=l[i];
			if(sz>=2){
				x[sz-1]=get(stk[sz],stk[sz-1]);
				if(x[sz-1]<mi||x[sz-1]>mx)sz--;
			}
		}
		x[sz]=mx;
		rep(i,1,sz){//计算积分
			int idx=stk[i].idx;
			ll B=-2*pt[idx].x;
			ll C=pt[idx].x*pt[idx].x+(pt[idx].y-b[tc])*(pt[idx].y-b[tc]);
			if(x[0]<=x[i-1]&&x[i]<=x[sz])ans+=INT(x[i-1],x[i],B,C);
		}
	}
}
int main(){
	fastio;
	cin>>n;
	rep(i,1,n)cin>>pt[i].x>>pt[i].y;
	cin>>m;
	rep(i,1,m)cin>>a[i]>>b[i];
	work();
	rep(i,1,m)swap(a[i],b[i]);
	rep(i,1,n)swap(pt[i].x,pt[i].y);
	work();
	cout<<fixed<<setprecision(10)<<ans;
	return 0;
}

标签:SDU,ld,ll,pt,sz,rep,2023,凸壳,tc
From: https://www.cnblogs.com/yoshinow2001/p/17744901.html

相关文章

  • 2023-2024-1学号20231407陈原《计算机基础与程序设计》第一周学习总结
    这个作业属于哪个课程2023-2024-1-计算机基础与程序设计这个作业要求是什么2023-2024-1计算机基础与程序设计第一周作业这个作业的目的是什么简单浏览《计算机概论》,提出疑问,并尝试解决问题    作业正文 https://www.cnblogs.com/CCCY12345/p/17744827.ht......
  • 20231006
    20231006NOIP#16(33daiOJ)总结时间安排7:40~8:00看题,\(A\)一眼切了,\(B\)会两档,\(C,D\)没想法。8:00~8:20写\(A\)的正解。8:20~8:40写\(B\)的\(30pts\)。8:40~8:50原来算错了\(C\)的爆搜复杂度,现在写了\(C\)的第一档。8:50~9:20会了\(D\)链的特殊性质写了......
  • 2023-2024-1 20231428《计算机基础与程序设计》第一周学习总结
           这个作业属于哪个课程2023-2024-1-计算机基础与程序设计            作业要求https://www.cnblogs.com/rocedu/p/9577842.html#WEEK01          这个作业的目标快速阅读教材,初步了解所学内容 ......
  • P9140 [THUPC 2023 初赛] 背包
    prologue这很难评(调了我1h,我都想紫砂了。还是典型得不重构就看不见系列。analysis如果我们还是一个正常人,那么我们大体上是能看到题目的加粗字,这个格式很明显符合我们的同余最短路的格式。(如若不知,请先出门直走)然后我们就要考虑这个同余最短路的实现。这个题目不同于往常......
  • 2023-10-06
    一、第一次直接就焊MCU了,C8T6都焊的乌漆嘛黑的,再也不用松香了。SMT报价发BOM和Gerber过去,总共遥控和核心板2块贴片,不包含运费物料。要600大洋。。。。。 二、买了块练习板,又买了几块C8T6,总不可能焊坏100次。1.MCU焊接方法:所有焊点上锡,点焊法。  2.小元器件贴片:焊点上锡......
  • 武汉大学2023年新生程序设计竞赛(同步赛)
    C.覆叶之交(线段树+离散化+扫描线)输入格式:输出格式:输入00230032-1-111输出11说明线段树+离散化+扫描线#include<bits/stdc++.h>#defineIOSios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr)#definelowbit(ver)ver&(-ver)......
  • 2022-2023 ICPC Central Europe Regional Contest
    The1stUniversalCup.Stage8:SloveniaD.Deforestation这道题出题人比较谜语人,对于一个分叉点,只能选择若干个儿子和父亲组成一组,剩下的儿子之间不能相互组合。所以从叶子节点开始贪心处理就好。对于一个父亲他有若干个儿子,就贪心的选择剩下部分更小的儿子。#include<bits......
  • 2023.10.5测试
    \[\text{NOIP模拟赛-2023.10.5}\]T1魔法少女定义\(f(i)\)为\(i\)所有约数的异或和,求\(f(1)\simf(n)\)的异或和\(1\leqn\leq10^{14}\)容易想到枚举约数然后计算出约数出现的次数并对答案做贡献,复杂度\(\mathcal{O}(n)\)发现约数\(x\)出现的次数即\(\left\lfloor......
  • 2023-2024-1 学号20231315《计算机基础与程序设计》第二周学习总结
    学期:2023-2024-1学号:20231315《计算机基础与程序设计》第二周学习总结作业信息这个作业属于哪个课程2023-2024-1《计算机基础与程序设计》这个作业要求在哪里2023-2024-1《计算机基础与程序设计》这个作业的目标学习计算机科学概论第1章和《C语言程序设计》第1......
  • 【GJOI 2023.10.5 T1】 雷老师的正偏态分布
    雷老师的正偏态分布题意:给出一个长度为\(n\)的\(a\)数组,其中\(1\lea_i\leV,1\lei\len\)。统计其中的满足平均数严格小于中位数且大小为奇数的子集数量,\(n\le100,V\le800\),时限\(4\)s。输入:510127910输出:8首先,可以考虑排序,保证一个子集中小......