poj1177——Picture

来源:互联网 发布:c语言表白代码我爱你 编辑:程序博客网 时间:2024/05/16 18:57

线段树+离散化+扫描:

离散化的概念可以参考99年国家集训队陈宏的论文。

重点理解两个公式:[1]   ans+=st[1].segnum *2*(yline[i+1].x-yline[i].x);

                           [2]   ans+=abs(st[1].sum-lsum);

首先,读入数据,存入yline[]数组中,并将y坐标存入INDEX[]数组中,其中,yline[]的结构应该为:

 ;

接下来,对yline[]数组以x为关键字进行排序,INDEX[]数组同样得排序,并对INDEX[]数组进行去重操作,得到剩下的不同的y值为cnt个;

现在,到了建树阶段:这里建树,是以[0,cnt-1]为起始点建树的,也就是说st[1].l=0,st[1].r=cnt-1;因为这样建的树的话,每个节点的l,r值是和INDEX[]数组里面的y值相对应的,而且,用的是超元线段,这样,可以节省很多空间和操作的时间,当然,建完树,应该顺便初始化的,st[max]的结构是:

 

现在,从0开始,对yline[]数组进行扫描,扫描到左边,进行Insert操作,如果是右边,则进行Delete操作,并且,每次都对数进行更新,即getlen(index)和getsegnum(index)两个操作

对于ans+=abs(st[1].sum-lsum),这个等式,应该不难理解,每次加上|线段树中所覆盖的总长度-上次还剩的长度|即更新的长度;

而 ans+=st[1].segnum *2*(yline[i+1].x-yline[i].x)中,难理解的是st[1].segnum 。对于这个的值,就是该区间中,有多少的不相交的段数。而求这个值的过程中,就用的了cover、st[i].lcover、st[i].rcover,而且,对轴进行了离散化。自己理解下,不是很好明白,但你必须弄懂!

现在贴上代码:

 

原创粉丝点击