PKU3277离散化+线段树

对于x坐标先进行一个排序 用一个数组记录它们是第几大 这样就把非常大的数压缩得很小 线段树中叶子节点记录的就是相邻x的区间
对于每个节点记录最高的h hcount代表这个区间有多少个高度 最后用每个区间宽度×h 在树中即可计算area
#include<stdio.h>
#include
<math.h>
#include
<string.h>
#include
<stdlib.h>
struct node
{
    node 
* pl, * pr;
    
int iL, iR;
    
int height;
    
int hCount;
}
line[160008];

int x1[40002], x2[40002];
int x[80004];
int xh[80004];
int h[40002];
int n;

int lineCount;
__int64 area;

node 
* newNode()
{
    node 
*pt = &line[lineCount++];
    memset(pt,
0,sizeof(node));
    
return pt;
}


node 
* makeTree(int i, int j)
{
    node 
* root=newNode();
    root
->iL=i;
    root
->iR=j;
    
if(j-i>1)
    
{
        
int mid=(i+j)/2;
        root
->pl=makeTree(i,mid);
        root
->pr=makeTree(mid,j);
    }

    
return root;
}


void height(node * root, int h)
{
    root
->hCount=1;
    root
->height=h;
}


void update(node * root, int x1, int x2, int h)
{
    
    
if(x[root->iL]==x1 && x[root->iR]==x2 && h > root->height)
    
{
        height(root,h);
        
return;
    }


    
if(root->iR - root->iL <= 1)
        
return;

    
if(root->hCount==1)
    
{
        
if(root->height >= h)
            
return;
        height(root
->pl,root->height);
        height(root
->pr,root->height);
    }


    root
->hCount=2;
    
if(root->height < h)root->height=h;

    
if(x[root->pl->iR]>x1)
    
{
        
if(x[root->pl->iR]>=x2)
            update(root
->pl, x1, x2, h);
        
else
        
{
            
int mid=(root->iL + root->iR)/2;
            update(root
->pl,x1,x[mid],h);
            update(root
->pr,x[mid],x2,h);
        }

    }

    
else
    
{
        update(root
->pr,x1,x2,h);
    }

    
}



void count(node * root, int i, int j)
{
    
if(root->hCount==1)
    
{
        __int64 a, b;
        a
=x[root->iR]-x[root->iL];
        b
=root->height;
        area
+=a*b;
        
return;
    }

    
if(root->iR - root->iL <= 1 || root->hCount==0)
        
return;

    
if(root->pl->iR>i)
    
{
        
if(root->pl->iR>=j)
        
{
            count(root
->pl,i,j);
        }

        
else
        
{
            
int mid=(root->iL+root->iR)/2;
            count(root
->pl,i,mid);
            count(root
->pr,mid,j);
        }

    }

    
else
    
{
        count(root
->pr,i,j);
    }

}



int cmp ( const void *a , const void *b )
{
    
return *(int *)a - *(int *)b;
}


int main()
{

    
while(scanf("%d"&n) ==1)
    
{
        memset(x,
0,sizeof(x));
        memset(x1,
0,sizeof(x1));
        memset(x2,
0,sizeof(x2));
        memset(xh,
0,sizeof(xh));
        memset(h,
0,sizeof(h));

        area
=0;
        
int i;
        
for(i=0;i<n;i++)
        
{
            scanf(
"%d%d%d",&x1[i],&x2[i],&h[i]);
            xh[
2*i]=x1[i];
            xh[
2*i+1]=x2[i];
        }


        qsort(xh,
2*n,sizeof(xh[0]),cmp);



        
int max_i=0;
        
for(i=0;i<2*n;i++)
            
if(xh[i]!=xh[i-1|| i==0)
                x[max_i
++]=xh[i];

/*        for(i=0;i<max_i;i++)
            printf("%d  ", x[i]);
        printf("\n");
*/


        lineCount
=0;

        node 
* root=makeTree(0,max_i-1);
        
for(i=0;i<n;i++)
        
{
            update(root,x1[i],x2[i],h[i]);
        }


        count(root,
0,max_i-1);

        printf(
"%I64d\n",area);

    }

    
return 0;
}
原文地址:https://www.cnblogs.com/SQL/p/922507.html