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

来源:互联网 发布:人才外包知乎 编辑:程序博客网 时间:2024/05/14 16:17

扫描线求每次的上下已有边长,同时区间合并记录边长的分布情况乘以高度差求出高度的变长


#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 400005vector<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;}


0 0