zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    com.jsj.dao====新闻发布系统(4)
    java类加载器,getClassLoader()
    类名.class的理解
    static{}和{}===静态模块和普通模块的理解
    com.jsj.factory====新闻发布系统(3)
    怎么做(我直接敲代码,有解释)===新闻发布系统(2)
    (8)小项目--界面的代码
    (7) 小项目
    2 Servlet(1)
    RMQ之ST算法模板
  • 原文地址:https://www.cnblogs.com/SQL/p/922507.html
Copyright © 2011-2022 走看看