BZOJ2300 防线修筑

附上代码

#include<set>
#include<cmath>
#include<queue>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7fffffff
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,X,Y,vis[200005],m,cnt,Q,tot,belong[200005];
struct q
{
    int opt,id;
}query[200005];
struct p
{
    int x,y,id;
    bool operator < (const p &a) const
    {
        return x<a.x;
    }
}node[200005],have[200005];
p operator - (p a,p b) {p c;c.x=a.x-b.x,c.y=a.y-b.y;return c;}
int operator * (p a,p b) {return a.x*b.y-a.y*b.x;}
bool cmp (const p & a,const p & b)
{
    int tmp=(a-have[1])*(b-have[1]);
    if(tmp==0) return a.x<b.x;
    return tmp<0;
}
int stack[200005],top,now;
double sum,ans[200005];
double dis(p x,p y)
{
    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
}
set<p> buhui;
set<p> :: iterator it1,it2,L,R,end;
void insert(int x)
{
    p heihei=node[x],l,r;
    it1=buhui.upper_bound(heihei);
    it2=it1,it1--;
    l=*it1,r=*it2;
    if((r-l)*(heihei-l)<=0) return ;
    sum-=dis(l,r);
    while(it1!=buhui.begin())
    {
        L=it1;
        L--;
        l=*L,r=*it1;
        if((r-heihei)*(l-heihei)<=0) 
        {
            sum-=dis(r,l);
            buhui.erase(it1);
            it1=L;
        }
        else break;
    }
    sum+=dis(heihei,*it1);
    while(1)
    {
        R=it2;
        R++;
        if(R==buhui.end()) break;
        l=*it2,r=*R;
        if((r-heihei)*(l-heihei)<=0) 
        {
            sum-=dis(l,r);
            buhui.erase(it2);
            it2=R;
        }
        else break;
    }
    sum+=dis(heihei,*it2);
    buhui.insert(heihei);
}
int main()
{
    int i,j;
    /*freopen("bzoj2300.in","r",stdin);
    freopen("bzoj2300.out","w",stdout);*/ 
    n=read(),X=read(),Y=read();
    m=read();
    node[++cnt].x=0,node[cnt].y=0;
    node[++cnt].x=n,node[cnt].y=0;
    node[++cnt].x=X,node[cnt].y=Y;
    for(i=1;i<=m;i++)
        node[++cnt].x=read(),node[cnt].y=read(),node[cnt].id=i,belong[i]=cnt;
    Q=read();
    for(i=1;i<=Q;i++)
    {
        query[i].opt=read();
        if(query[i].opt==1) query[i].id=read(),vis[query[i].id]=1;
    }
    for(i=1;i<=cnt;i++)
        if(!vis[node[i].id]) have[++tot]=node[i];
    sort(have+2,have+tot+1,cmp);
    stack[++top]=1,stack[++top]=2;
    for(i=3;i<=tot;i++)
    {
        while(top>1&&(have[stack[top]]-have[stack[top-1]])*(have[i]-have[stack[top-1]])>0) top--;
        stack[++top]=i;
    }
    for(i=1;i<=top;i++)
        buhui.insert(have[stack[i]]);
    for(i=1;i<top;i++) sum+=dis(have[stack[i]],have[stack[i+1]]);
    for(i=Q;i>=1;i--)
    {
        if(query[i].opt==2) ans[++now]=sum;
        else insert(belong[query[i].id]);
    }
    for(i=now;i>=1;i--) printf("%.2lf\n",ans[i]);
    //printf("%.2lf",ans);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值