POJ 1151(HDU 1542)Atlanttis【矩形面積及び線分樹+離散化+走査線テンプレート】


Description
The e e are several ancint Greexts texts that contan descriptions of the fabled island Atlant tis.Some of these textseve maps of the island.But unfortunally,these maps describe different regions.Afront.voluntered to write a program that calculates this quantity.
Input
The input consists of several test cases.Each test case starts with a line containing a single integer n(1<=n==100)of available maps.The n following line describe one map each.Each of these line s containtens fourem 1;y 1;x 2;y 2(0<=x 1<=100000;、0<=y 1The input file is terminated by a line containing a single 0.Don't process it.
Output
For each test case、your program shoutputone section.The first line of each sectction must be「Test case\脸k」、where k is the number of the test case(starting with 1).The second onemusbe.The second one mmusbe「Totaltaltaleeeeeex thetaltaltaltaltaltaltrtrtrtrtrtraaaaaaaatrtrtrtrtrtrtrtrtrtrtraaaaaaaaaaaaaaaaaaaaaatrtrtrtrtrtrtrtrtrtrtrtrtrtraaaaaaを選択します.printed exact to two digits to the right of the decimal point.
Output a blank line after each test case.
Sample Input
2
10 10 20 20
15 15 25 25.5
0
Sample Output
Test case #1
Total explored area: 180.00 
このテンプレートはkuangbinから抜粋します.リンクを開くにはクリックしてください.
走査線法:左から右へ(右から左へ)または下から上へ(上から下へ)スキャンした多角形全体(または奇形.複数の長方形を重ねた図形)を想定しています.縦方向のスキャンであれば、離散化横座標であり、水平方向のスキャンであれば離散化縦座標である.以下の解析は横座標を離散化し,下から上へスキャンした.
   スキャンする前に、すべての長方形の上の下を保存し、それらの高さによって並べ替えます.また上の方から彼に1つの値をあげます.下の方から1つの値をあげます.構造体ですべての上の下を保存します. 
struct segment{double,r,h; //l,rはこの上と下の左右座標を示し、hはこの辺の高さint fである. //与えられた値、1または-1}
次に走査線を下から上にスキャンし、上から下に出会うごとに停止します.この線分を総区間に投影します.この投影は線分を挿入して削除します.彼らに与えられた値の1または-1を覚えていますか?下は1で、下にスキャンすれば、全区間に線分を挿入するのに相当します.上は-1で、上は総区間で線分を削除するのに相当します.(挿入削除が抽象的だというなら、下にスキャンして、全区間に投影して、対応する区間の値は全部1増加して、上にスキャンして対応する区間の値は全部1マイナスになります.総区間のある区間の値が0なら、線分がカバーされていないと説明します.正数であれば、マイナスになりますか?不可能です.自分で考えてみてください.下の方
一つの上の下にスキャンして、全体の区間に投影した後、全区間が現在覆われている全体の長さを判断し、次の辺の高さから現在のこの辺の高さを差し引いて、総区間で覆われている長さに乗ると、一つの面積が得られます.
下のテンプレートは左から右にスキャンされているようです.
#include
#include
#include
using namespace std;
#define MAXN 201
struct Node
{
    int l,r;//        
    int c;//c        
    double cnt,lf,rf;//
    //cnt         ,rf,lf                 
}segTree[MAXN*3];     
struct Line
{
    double x,y1,y2;
    int f;
}line[MAXN];
//       y          ,
//x    x  ,y1,y2                
//     ,      f 1,    -1,
//        ,         ,nod    c 

bool cmp(Line a,Line b)//sort     
{
    return a.x < b.x;
}     

double y[MAXN];//  y     
void Build(int t,int l,int r)//     
{
    segTree[t].l=l;segTree[t].r=r;
    segTree[t].cnt=segTree[t].c=0;
    segTree[t].lf=y[l];
    segTree[t].rf=y[r];
    if(l+1==r)  return;
    int mid=(l+r)>>1;
    Build(t<<1,l,mid);
    Build(t<<1|1,mid,r);//     
}     
void calen(int t)//    
{
    if(segTree[t].c>0)
    {
        segTree[t].cnt=segTree[t].rf-segTree[t].lf;
        return;
    }    
    if(segTree[t].l+1==segTree[t].r)  segTree[t].cnt=0;
    else  segTree[t].cnt=segTree[t<<1].cnt+segTree[t<<1|1].cnt;
}     
void update(int t,Line e)//    e,      
{
    if(e.y1==segTree[t].lf&&e.y2==segTree[t].rf)
    {
        segTree[t].c+=e.f;
        calen(t);
        return;
    }    
    if(e.y2<=segTree[t<<1].rf)  update(t<<1,e);
    else if(e.y1>=segTree[t<<1|1].lf)  update(t<<1|1,e);
    else
    {
        Line tmp=e;
        tmp.y2=segTree[t<<1].rf;
        update(t<<1,tmp);
        tmp=e;
        tmp.y1=segTree[t<<1|1].lf;
        update(t<<1|1,tmp);
    }    
    calen(t);
}    
int main()
{
    int i,n,t,iCase=0;
    double x1,y1,x2,y2;
    while(scanf("%d",&n),n)
    {
        iCase++;
        t=1;
        for(i=1;i<=n;i++)
        {
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            line[t].x=x1;
            line[t].y1=y1;
            line[t].y2=y2;
            line[t].f=1;
            y[t]=y1;
            t++;
            line[t].x=x2;
            line[t].y1=y1;
            line[t].y2=y2;
            line[t].f=-1;
            y[t]=y2;
            t++;
        } 
        sort(line+1,line+t,cmp);
        sort(y+1,y+t);   
        Build(1,1,t-1);
        update(1,line[1]);
        double res=0;
        for(i=2;i