[HAOI2011] 防线修建 题解

容易发现答案即为重要城市的上凸壳的长度。考虑将正序删点转化为倒序删点,就变成了经典动态加点求凸壳。

对于动态加点求凸壳的问题,我们考虑使用 set 进行维护。因为这样可以较快的找到加入点 \(y\) 在凸壳上的前驱 \(x\) 和后继 \(z\)。我们先判断 \(y\) 是否能加入上凸壳,相当于询问 \(x,y,z\) 三点构成的上凸壳中有没有 \(y\)。若可以加入,就向左、右暴力递推,若自己的前驱/后继不满足要求,就将其删去;否则跳出循环。

考虑证明这样做的时间复杂度正确性。由于每个点最多被删去一次,所以暴力递推的总次数是 \(O(m)\) 的,因此时间复杂度为 \(O(m\log m)\) 的。

#include<bits/stdc++.h>
#define dx(x,y) (xc[x]-xc[y])
#define dy(x,y) (yc[x]-yc[y]) 
using namespace std;
const int N=1e5+5;
struct idx{int x;};double ans,as[N];
int n,q,xc[N],yc[N],dl[N],vis[N];
bool operator<(idx x,idx y){
	return xc[x.x]==xc[y.x]?yc[x.x]<yc[y.x]:xc[x.x]<xc[y.x];
}int tp,num,st[N],id[N],sum;set<idx>s;
int cmp(int x,int y){
	return xc[x]==xc[y]?yc[x]<yc[y]:xc[x]<xc[y];
}int check(int x,int y,int z){
	return dy(y,x)*dx(z,y)<=dy(z,y)*dx(y,x);
}double line(int x,int y){
	return sqrt(pow(dx(x,y),2)+pow(dy(x,y),2));
}double del(int x,int y,int z){
	return line(x,y)+line(y,z)-line(x,z);
}void add(int x){
	auto itl=s.lower_bound({x}),itr=itl;itl--;
	if(check(itl->x,x,itr->x)) return;
	ans+=del(itl->x,x,itr->x);
	while(1){
		itl=s.lower_bound({x}),itr=--itl;
		if(itr==s.begin()) break;itl--;
		if(!check(itl->x,itr->x,x)) break;
		ans-=del(itl->x,itr->x,x),s.erase(itr);
	}while(1){
		itr=s.upper_bound({x}),itl=itr++;
		if(itr==s.end()) break;
		if(!check(x,itl->x,itr->x)) break;
		ans-=del(x,itl->x,itr->x),s.erase(itl);
	}s.insert({x});
}int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	scanf("%d%d%d%d",&xc[2],&xc[3],&yc[3],&n),n+=3;
	for(int i=4;i<=n;i++) scanf("%d%d",&xc[i],&yc[i]);
	scanf("%d",&q);
	for(int i=1;i<=q;i++){
		int opt,c;scanf("%d",&opt);
		if(opt<2) scanf("%d",&c),vis[dl[i]=c+3]=1;
	}for(int i=1;i<=n;i++) if(!vis[i]) id[++num]=i;
	sort(id+1,id+num+1,cmp);
	for(int i=1;i<=num;st[++tp]=id[i++])
		while(tp>1&&check(st[tp-1],st[tp],id[i])) tp--;
	for(int i=1;i<=tp;i++) s.insert({st[i]});
	for(int i=1;i<tp;i++) ans+=line(st[i],st[i+1]);
	for(int i=q;i;i--){
		if(dl[i]>0) add(dl[i]);
		else as[++sum]=ans;
	}for(int i=sum;i;i--) printf("%.2lf\n",as[i]);
	return 0;
}
posted @ 2025-06-26 15:16  white_tiger  阅读(16)  评论(0)    收藏  举报