hdu1828 线段树之周长并

来源:互联网 发布:网络浏览器有哪些 编辑:程序博客网 时间:2024/05/29 23:22

看完题目之后,完全没想法,懵了一小时之后,果断搜索各种解题。看了几个结题报告之后,感觉思维暴强啊,我咋就没想到呢??? 看来自己思维暴弱啊,路还很长啊。。。思路就不写了,网上到处都是,留个代码作纪念。。。


ACcode:

#include<stdio.h>#include<math.h>#include<iostream>#include<algorithm>using namespace std;const int size=5555;int X[size<<1];struct Line{    int lx,rx,y;    int f;    Line(){}    Line(int a,int b,int c,int d): lx(a),rx(b),y(c),f(d) {}    bool operator < (const Line &tmp) const {        return y<tmp.y;    }}line[size<<1];struct Seg{    int ld,rd;    int cover;    int num,len;}tre[size<<2];int Fin(int key,int len){    int l=0,r=len;    while (l<=r)    {        int m=(l+r)>>1;        if (X[m]==key) return m;        else if (X[m]<key) l=m+1;        else r=m-1;    }    return -1;}void build(int rt,int l,int r){    tre[rt].ld=tre[rt].rd=-1;    tre[rt].num=tre[rt].len=0;    tre[rt].cover=0;    if (l==r) return ;    int m=(l+r)>>1;    build(rt<<1,l,m);    build(rt<<1|1,m+1,r);}void PushUp(int rt,int l,int r){    if (tre[rt].cover>0)    {        tre[rt].num=1;        tre[rt].len=X[r+1]-X[l];        tre[rt].ld=l; tre[rt].rd=r;    }    else if (l==r)    {        tre[rt].len=tre[rt].num=0;        tre[rt].ld=tre[rt].rd=-1;    }    else    {        int m=(l+r)>>1;        tre[rt].len=tre[rt<<1].len+tre[rt<<1|1].len;        if (tre[rt<<1].len>0) tre[rt].ld=tre[rt<<1].ld;        else tre[rt].ld=tre[rt<<1|1].ld;        if (tre[rt<<1|1].len>0) tre[rt].rd=tre[rt<<1|1].rd;        else tre[rt].rd=tre[rt<<1].rd;        tre[rt].num=tre[rt<<1].num+tre[rt<<1|1].num;        if (tre[rt<<1].rd==m&&tre[rt<<1|1].ld==(m+1))            tre[rt].num--;    }}void update(int rt,int l,int r,int L,int R,int v){     if (L<=l&&r<=R)     {         tre[rt].cover+=v;         PushUp(rt,l,r);         return ;     }     int m=(l+r)>>1;     if (L<=m) update(rt<<1,l,m,L,R,v);     if (R>m)  update(rt<<1|1,m+1,r,L,R,v);     PushUp(rt,l,r);}int main(){    int n,i,k,m,ans,last;    int x1,x2,y1,y2,L,R;    while (~scanf("%d",&n))    {        for (m=i=0;i<n;i++)        {            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);            X[m]=x1;X[m+1]=x2;            line[m++]=Line(x1,x2,y1,1);            line[m++]=Line(x1,x2,y2,-1);        }        sort(X,X+m);        sort(line,line+m);        k=unique(X,X+m)-X-1;        line[m]=line[m-1];        build(1,0,k);        for (last=ans=i=0;i<m;i++)        {            L=Fin(line[i].lx,k);            R=Fin(line[i].rx,k)-1;            update(1,0,k,L,R,line[i].f);            ans+=abs(tre[1].len-last)+tre[1].num*2*(line[i+1].y-line[i].y);            last=tre[1].len;        }        printf("%d\n",ans);    }    return 0;}