线段树+离散化+扫描:
离散化的概念可以参考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,而且,对轴进行了离散化。自己理解下,不是很好明白,但你必须弄懂!
现在贴上代码: