ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

bzoj 3116 登顶计划题解

2021-02-10 23:04:44  阅读:199  来源: 互联网

标签:oth sz sta 题解 long double vec 3116 bzoj


/*
{
######################
#       Author       #
#        Gary        #
#        2021        #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
struct vec{
	long double x,y;
	long double operator * (vec oth){
		return x*oth.y-y*oth.x;
	}
	vec operator - (vec oth){
		return vec{x-oth.x,y-oth.y};
	}
	vec operator + (vec oth){
		return vec{x+oth.x,y+oth.y};
	}
};
bool cmp(vec A,vec B){
	return A.x<B.x;
}
const int MAXN=2e5+233;
const long double eps=1e-7;
int n;
vec a[MAXN];
int sz;
vec sta[MAXN];
int sta2[MAXN];
vector<vec> ip;
void cross(vec A,vec B,vec C,vec D){
	long double k=(A.y-B.y)/(A.x-B.x);
	long double b=A.y-A.x*k;
	long double k2,b2;
	k2=(C.y-D.y)/(C.x-D.x);
	b2=C.y-C.x*k2;
	long double x,y;
	if(abs(k-k2)<eps) return;
	if(C.x>D.x) swap(C,D);
	x=(b2-b)/(k-k2);
	y=x*k+b;
	if(x+eps<D.x&&x-eps>C.x){
		ip.PB(vec{x,y});
	}
}
int le[MAXN],ri[MAXN],id[MAXN];
long double tar[MAXN];
bool equ(vec A,vec B){
	return abs(A.x-B.x)<eps&&abs(A.y-B.y)<eps;
}
vector<int> g[MAXN];
long double dis[MAXN];
long double rest[MAXN];
long double get(int u,int v){
	if(u>v) swap(u,v);
	return dis[v]-dis[u];
}
void dfs(int now){
	for(auto it:g[now]){
		rest[it]=rest[now]+get(it,now); 
		dfs(it);
	}
}
int main(){
	scanf("%d",&n);
	rb(i,1,n) scanf("%Lf%Lf",&a[i].x,&a[i].y);
	sz=0;
	rb(i,1,n) ip.PB(a[i]);
	rb(i,1,n){
		while(sz>=2&&(sta[sz-1]-sta[sz])*(a[i]-sta[sz])<eps) {
			cross(sta[sz-1],sta[sz],a[i-1],a[i]);
			--sz;
		}
		sta[++sz]=a[i];
	}
	sz=0;
	rl(i,n,1){
		while(sz>=2&&(sta[sz-1]-sta[sz])*(a[i]-sta[sz])>-eps) {
			cross(sta[sz-1],sta[sz],a[i+1],a[i]);
			--sz;
		}
		sta[++sz]=a[i];
	}
	sort(ALL(ip),cmp);
	vector<vec> v;
	vec last=vec{INF,INF};
	for(auto it:ip){
		if(equ(last,it)){
			continue;
		}
		last=it;
		v.PB(it);
	}
	int m=v.size();
	int to=1;
	rep(i,m){
		while(to<=n&&a[to].x+eps<v[i].x)++to;
		if(to<=n&&equ(a[to],v[i])) id[to]=i;
	}
	rep(i,m){
//		printf("(%.6Lf %.6Lf)\n",v[i].x,v[i].y);
		le[i]=ri[i]=i;
		tar[i]=v[i].y;
	}
	sz=0;
	rep(i,m){
		while(sz>=2&&(sta[sz-1]-sta[sz])*(v[i]-sta[sz])<eps) {--sz;}
		if(sz>=1&&sta[sz].y>v[i].y) le[i]=sta2[sz],tar[i]=sta[sz].y;
		sta[++sz]=v[i];
		sta2[sz]=i;
	}
	sz=0;
	rl(i,m-1,0){
		while(sz>=2&&(sta[sz-1]-sta[sz])*(v[i]-sta[sz])>-eps) {--sz;}
		if(sz>=1&&sta[sz].y>v[i].y){
			ri[i]=sta2[sz];
			if(v[ri[i]].y>tar[i]) tar[i]=v[ri[i]].y;
//			cout<<i<<endl;
		}
		sta[++sz]=v[i];
		sta2[sz]=i;
	}
	int root=0;
	rep(i,m){
		if(ri[i]==le[i]) root=i;
	}
	stack<pair<long double ,int> > stk;
	rep(i,m){
		if(i==root) continue;
		while(!stk.empty()&&stk.top().FIR<=tar[i]+eps){stk.pop();}
		if(v[le[i]].y>v[ri[i]].y){
			if(stk.empty()||stk.top().SEC<=le[i]) g[le[i]].PB(i);
			else g[stk.top().SEC].PB(i); 
		}
		stk.push(II(tar[i],i));
	}
	while(!stk.empty()) stk.pop();
	rl(i,m-1,0){
		if(i==root) continue;
		while(!stk.empty()&&stk.top().FIR<=tar[i]+eps){stk.pop();}
		if(v[ri[i]].y>=v[le[i]].y){
			if(stk.empty()||stk.top().SEC>=ri[i]) g[ri[i]].PB(i);
			else g[stk.top().SEC].PB(i); 
		}
		stk.push(II(tar[i],i));
	}
//	rep(i,m){
//		cout<<le[i]<<' '<<ri[i]<<' ';
//		printf("%.6Lf\n",tar[i]);
//	}
	rb(i,1,m){
		double X,Y;
		X=v[i].x-v[i-1].x;
		Y=v[i].y-v[i-1].y;
		X=X*X;
		Y=Y*Y;
		dis[i]=sqrt(X+Y);
		dis[i]+=dis[i-1];
	}
	rest[root]=0;
	dfs(root);
	rb(i,1,n){
		printf("%.6Lf\n",rest[id[i]]);
	}
	return 0;
}

标签:oth,sz,sta,题解,long,double,vec,3116,bzoj
来源: https://www.cnblogs.com/gary-2005/p/14396906.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有