BZOJ2300: [HAOI2011]防线修建

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2300

(我只是在发以前写过的题。。

因为题目没说强制在线,所以离线乱搞就可以了。先把点删掉然后一个一个插进去,维护一个动态凸包就可以了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
#define esp 1e-7
#define ll long long
#define oo 1152921504606846976
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
using namespace std;
const int maxn=200500,maxm=17;
struct P{int x,y;
}a[maxn],del[maxn];
set<P> q;
double now,ans[maxn];
int top,n,m,mark[maxn],t1,t2,b[maxn];
ll read(){
    int x=0,f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    return x*f;
}
P operator -(P a,P b){
    return (P){a.x-b.x,a.y-b.y};
}
double operator *(P a,P b){
    return (a.x*b.y-a.y*b.x);
}
int cmp(double x){
    if (fabs(x)<esp) return 0;
    if (x>0) return 1;
    return -1;
}
double dis(P a,P b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool operator <(P a,P b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
void insert(P x){
    set<P>::iterator r=q.lower_bound(x),l=r,t; l--;
    if ((*r-*l)*(x-*l)<0) return;
    now-=dis(*l,*r);
    while (1){
        t=r++;
        if (r==q.end()) break; 
        if ((*r-x)*(*t-x)>0) break;
        now-=dis(*r,*t);
        q.erase(t); 
    }
    while (l!=q.begin()){
        t=l--;
        if ((*t-x)*(*l-x)>0) break;
        now-=dis(*l,*t);
        q.erase(t);
    }
    q.insert(x); l=r=q.find(x); l--;r++;
    now+=dis(*r,x)+dis(*l,x);
}
int main(){
    int op,x;
    n=read(); 
    P bas;
    bas.x=read(); bas.y=read();
    q.insert((P){0,0}); q.insert((P){n,0}); q.insert(bas);
    now+=dis((P){0,0},bas)+dis((P){n,0},bas);
    m=read();
    rep(i,1,m) a[i].x=read(),a[i].y=read();
    int Q;
    Q=read();
    rep(i,1,Q){
        op=read(); 
        if (op==1) {x=read();del[++t1]=a[x]; mark[x]=1;}
        else b[++t2]=t1;    
    }
    rep(i,1,m) if (!mark[i]) insert(a[i]);
    int t=t1;
    down(i,t2,1){
        while (t>b[i]) insert(del[t--]);
        ans[i]=now;
    }
    rep(i,1,t2) printf("%.2lf\n",ans[i]);
    return 0;
}

 

posted on 2015-12-01 19:43  ctlchild  阅读(147)  评论(0编辑  收藏  举报

导航