zoukankan      html  css  js  c++  java
  • 【BZOJ2300】【HAOI2011】—防线修建(set维护动态凸包)

    传送门

    题意:给你一堆点,支持删去一个点,询问当前凸包的周长

    考虑一个一个删去不好处理,离线后一个个加入

    就成了一道动态凸包的板子了
    setset维护一下就可以了

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=res*10+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=200005;
    const double pi=acos(-1);
    const double eps=1e-8;
    struct point{
    	double x,y;
    	point(double a=0,double b=0){
    		x=a,y=b;
    	}
    	friend inline point operator +(const point &a,const point &b){
    		return point(a.x+b.x,a.y+b.y);
    	}
    	friend inline point operator -(const point &a,const point &b){
    		return point(a.x-b.x,a.y-b.y);
    	}
    	friend inline double operator *(const point &a,const point &b){
    		return (a.x*b.y-a.y*b.x);
    	}
    	friend inline bool operator <(const point &a,const point &b){
    		return (a.x==b.x)?(a.y<b.y):(a.x<b.x);
    	}
    	inline double calc(){
    		return sqrt(x*x+y*y);
    	}
    }p[N];
    struct ask{
    	int x,op;
    	double ans;
    }a[N];
    int n,m,q,vis[N];
    double ans;
    set<point> st;
    #define it set<point>::iterator
    inline void insert(point x){
    	it r=st.lower_bound(x),l=r,t;l--;
    	if((*r-*l)*(x-*l)<0)return;
    	ans-=(*r-*l).calc();
    	while(1){
    		t=r,r++;
    		if(r==st.end())break;
    		if((*r-x)*(*t-x)>0)break;
    		ans-=(*r-*t).calc();
    		st.erase(t);
    	}
    	while(l!=st.begin()){
    		t=l,l--;
    		if((*l-x)*(*t-x)<0)break;
    		ans-=(*l-*t).calc();
    		st.erase(t);
    	}
    	st.insert(x);
    	l=r=st.find(x);
    	l--,r++;
    	ans+=(*r-x).calc(),ans+=(*l-x).calc();
    }
    int main(){
    	n=read();
    	point l=point(0,0),r=point(n,0),cap;
    	st.insert(point(0,0)),st.insert(point(n,0));
    	cap.x=read(),cap.y=read();
    	st.insert(cap);
    	ans+=(cap-l).calc(),ans+=(cap-r).calc();
    	m=read();
    	for(int i=1;i<=m;i++)p[i].x=read(),p[i].y=read();
    	q=read();
    	for(int i=1;i<=q;i++){
    		a[i].op=read();
    		if(a[i].op==1){
    			a[i].x=read(),vis[a[i].x]=1;
    		}
    	}
    	for(int i=1;i<=m;i++){
    		if(!vis[i])insert(p[i]);
    	}
    	for(int i=q;i;i--){
    		if(a[i].op==1){
    			insert(p[a[i].x]);
    		}
    		else a[i].ans=ans;
    	}
    	for(int i=1;i<=q;i++){
    		if(a[i].op==2)printf("%.2lf
    ",a[i].ans);
    	}
    }
    
  • 相关阅读:
    java初学
    数据库命名及设计规范(转)
    转-ASP.NET页面之间传递值
    程序员个人职业规划
    如何学习别人的代码(转)
    可映射的CSV读取引擎
    iTween扩展
    Unity3d中NGUI加强版血条(Healthbar)的制作
    Unity3D中寻路Navmesh的简单介绍
    多人网络(Valve开发文档翻译[起源引擎])(一)
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145658.html
Copyright © 2011-2022 走看看