您的位置:首页 > 其它

HDU 1828 Picture (线段树扫描线求周长并 区间合并)

2016-02-29 19:15 393 查看
扫描线求每次的上下已有边长,同时区间合并记录边长的分布情况乘以高度差求出高度的变长

#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f
#define maxn 400005

vector<int>v;
int cnt;
struct edge
{
int l,r;
int h;
int tag;
friend bool operator < (edge a,edge b)
{
return a.h<b.h;
}
} line[maxn];

struct node
{
int l,r;
int add;
int sum;
int num;
int lt,rt;
} T[maxn];

void add_edge(int x,int y,int h,int d)
{
line[cnt].l=x;
line[cnt].r=y;
line[cnt].h=h;
line[cnt++].tag=d;
}

void init(int l,int r,int k)
{
T[k].l=l;
T[k].r=r;
T[k].add=0;
T[k].sum=0;
T[k].num=0;
T[k].lt=T[k].rt=0;
if(l+1==r) return ;
int mid=(l+r)>>1;
init(l,mid,2*k);
init(mid,r,2*k+1);
}

inline void pushup(int k)
{
if(T[k].add) T[k].sum=v[T[k].r]-v[T[k].l],T[k].lt=T[k].rt=1;
else T[k].sum=T[2*k].sum+T[2*k+1].sum,T[k].lt=T[k].rt=0;
if(T[k].add) T[k].num=1;
else if(T[k].l+1==T[k].r) T[k].num=0;
else
{
if(T[2*k].rt&&T[2*k+1].lt) T[k].num=T[2*k].num+T[2*k+1].num-1;
else T[k].num=T[2*k].num+T[2*k+1].num;
T[k].lt=T[2*k].lt;
T[k].rt=T[2*k+1].rt;
}
}

void Insert(int d,int l,int r,int k)
{
if(T[k].l==l&&T[k].r==r)
{
T[k].add+=d;
pushup(k);
return ;
}
int mid=(T[k].l+T[k].r)>>1;
if(r<=mid) Insert(d,l,r,2*k);
else if(l>=mid) Insert(d,l,r,2*k+1);
else
{
Insert(d,l,mid,2*k);
Insert(d,mid,r,2*k+1);
}
pushup(k);
}

int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n)
{
v.clear();
cnt=0;
for(int i=0; i<n; i++)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
add_edge(x1,x2,y1,-1);
add_edge(x1,x2,y2,1);
v.push_back(x1);
v.push_back(x2);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
sort(line,line+cnt);
init(0,v.size()+1,1);
int ans=0;
for(int i=0; i<cnt; i++)
{
int x=lower_bound(v.begin(),v.end(),line[i].l)-v.begin();
int y=lower_bound(v.begin(),v.end(),line[i].r)-v.begin();
int p=T[1].sum;
if(i) ans+=T[1].num*(line[i].h-line[i-1].h)*2;
Insert(line[i].tag,x,y,1);
ans+=abs(T[1].sum-p);
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: