DarkBZOJ传送门
洛谷传送门
解析:
动态凸包裸题,由于只需要维护一个上凸壳,所以用map水平序维护会比较方便。
细节有点多,慢慢调吧。
动态凸包板子可以看这里:https://blog.csdn.net/zxyoi_dreamer/article/details/87879301
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<20|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
inline int getint(){
re char c;
re bool f=0;
while(!isdigit(c=gc()))if(c=='-')f=1;re int num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return f?-num:num;
}
}
using namespace IO;
map<int,int> conv;
typedef map<int,int>::iterator point;
inline pair<int,int> operator-(cs pair<int,int> &a,cs pair<int,int> &b){
return make_pair(a.first-b.first,a.second-b.second);
}
inline ll operator*(cs pair<int,int> &a,cs pair<int,int> &b){
return (ll)a.first*b.second-(ll)a.second*b.first;
}
inline bool inside(int x,int y){
if(!conv.size())return false;
if(x<conv.begin()->first||x>conv.rbegin()->first)return false;
if(conv.count(x))return conv[x]<=y;
map<int,int>::iterator r=conv.lower_bound(x),l=r;
--l;
return (make_pair(x,y)-*l)*(*r-*l)<=0;
}
inline double dist(cs pair<int,int> &a,cs pair<int,int> &b){
return sqrt((ll)(a.first-b.first)*(a.first-b.first)+(ll)(a.second-b.second)*(a.second-b.second));
}
double nowc;
inline void ins(int x,int y){
if(inside(x,y))return ;
point now=conv.find(x);
if(now!=conv.end()){
point pre=now,suf=now;
--pre,++suf;
nowc-=dist(*pre,*now)+dist(*suf,*now);
now->second=y;
nowc+=dist(*pre,*now)+dist(*suf,*now);
}
else {
conv[x]=y;
now=conv.find(x);
point pre=now,suf=now;
--pre,++suf;
nowc-=dist(*pre,*suf);
nowc+=dist(*pre,*now)+dist(*suf,*now);
}
point cur=conv.lower_bound(x);
point re i,j;
for(i=cur,--i,j=i,--j;i!=conv.begin()&&cur!=conv.begin();i=j--)
if((*i-*cur)*(*j-*cur)>=0){
nowc-=dist(*i,*j)+dist(*i,*cur);
nowc+=dist(*j,*cur);
conv.erase(i);
}
else break;
for(i=cur,++i,j=i,++j;i!=conv.end()&&j!=conv.end();i=j++)
if((*i-*cur)*(*j-*cur)<=0){
nowc-=dist(*i,*j)+dist(*i,*cur);
nowc+=dist(*j,*cur);
conv.erase(i);
}
else break;
}
cs int N=100005;
int n,x[N],y[N];
int First[N];
int q,typ[N<<1],opt[N<<1];
double ans[N<<1];int cnt;
signed main(){
n=getint();x[0]=getint(),y[0]=-getint();
conv[0]=0;
conv[n]=0;
conv[x[0]]=y[0];
nowc=dist(make_pair(0,0),make_pair(x[0],y[0]))+dist(make_pair(x[0],y[0]),make_pair(n,0));
n=getint();
for(int re i=1;i<=n;++i)x[i]=getint(),y[i]=-getint();
q=getint();
for(int re i=1;i<=q;++i){
if((typ[i]=getint())==1){
opt[i]=getint();
if(!First[opt[i]])First[opt[i]]=i;
}
}
for(int re i=1;i<=n;++i)if(!First[i])ins(x[i],y[i]);
for(int re i=q;i;--i){
switch(typ[i]){
case 1:{
if(i==First[opt[i]])
ins(x[opt[i]],y[opt[i]]);
break;
}
case 2:{
ans[++cnt]=nowc;
break;
}
}
}
for(int re i=cnt;i;--i)printf("%.2f\n",ans[i]);
return 0;
}