# 线段树+扫描线【bzoj1645】[USACO07OPEN]城市的地平线City Horizon

### Output

PS：记得开$long \ long$还有数组要开大！！

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#define int long long
#define R register

using namespace std;

const int gz=100008;

inline void in(R int &x)
{
R int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}

struct ode
{
int l,r,h,f;
bool operator <(const ode&a)const
{
return h<a.h;
}
}edge[gz<<1];

struct cod
{
int l,r;
int len,s;
}tr[gz<<2];

int n,x[gz],tot;

#define ls o<<1
#define rs o<<1|1

void build(R int o,R int l,R int r)
{
tr[o].l=l,tr[o].r=r;
tr[o].len=tr[o].s=0;
if(l==r)return;
R int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
}

inline void up(R int o)
{
if(tr[o].s)
tr[o].len=x[tr[o].r+1]-x[tr[o].l];
else if(tr[o].l==tr[o].r)
tr[o].len=0;
else tr[o].len=tr[ls].len+tr[rs].len;
}

void change(R int o,R int l,R int r ,R int k)
{
if(tr[o].l==l and tr[o].r==r)
{
tr[o].s+=k;
up(o);
return;
}
R int mid=(tr[o].l+tr[o].r)>>1;
if(r<=mid)change(ls,l,r,k);
else if(l>mid)change(rs,l,r,k);
else change(ls,l,mid,k),change(rs,mid+1,r,k);
up(o);
}

signed main()
{
in(n);
for(R int i=1,a,b,c;i<=n;i++)
{
in(a),in(b),in(c);
edge[++tot].l=a,edge[tot].h=0,edge[tot].r=b;
edge[tot].f=1;x[tot]=a;
edge[++tot].l=a,edge[tot].h=c;edge[tot].r=b;
edge[tot].f=-1;x[tot]=b;
}
sort(x+1,x+tot+1);
sort(edge+1,edge+tot+1);
R int new_n=1;
for(R int i=2;i<=tot;i++)
if(x[new_n]!=x[i])
x[++new_n]=x[i];
build(1,1,new_n);
R int ans=0;
for(R int i=1;i<=tot;i++)
{
R int l=lower_bound(x+1,x+new_n+1,edge[i].l)-x;
R int r=lower_bound(x+1,x+new_n+1,edge[i].r)-x-1;
change(1,l,r,edge[i].f);
ans+=(edge[i+1].h-edge[i].h)*tr[1].len;
}
printf("%lld",ans);
}

posted @ 2018-11-08 18:32  顾z  阅读(164)  评论(0编辑  收藏  举报