zoukankan      html  css  js  c++  java
  • poj 1177 线段树的应用

    题意很明确,推荐陈大牛的文章,内有此题的详细解题思路。http://www.flyioi.com/wc/
    http://162.105.81.212/JudgeOnline/problem?id=1177
    #include <iostream>
    #include <string>
    #include <math.h>
    using namespace std;

    const int MAX_N = 10001;

    int hash[2*MAX_N], str2[2*MAX_N] , hash2[2*MAX_N];
    int len[2*MAX_N] , leftcover[2*MAX_N] , rightcover[2*MAX_N] , numcover[2*MAX_N];
    struct In
    {
           int start;
           int end;
           int pos;
           bool flag;      
    }str[2*MAX_N];

    struct Node
    {
           int l;
           int r;
           int mid;  
           int sum;
    }node[3*MAX_N];
    //建树
    void B_Tree( int l , int r , int num){
              node[num].l = l;
              node[num].r = r;
              node[num].mid = (l+r)>>1;
              node[num].sum = 0;
              if( l+1 != r ){
                  B_Tree( l , node[num].mid , num<<1 );
                  B_Tree( node[num].mid , r , num<<1|1 );   
              }
    }
    //更新
    void Updata( int l , int r , int num ){
         if( node[num].sum > 0 ){   //当它已被覆盖时
              len[num] = hash2[ node[num].r ] - hash2[ node[num].l ];  //并集区间的长度
              leftcover[num] = rightcover[num] = 1;    //表示左区间和右区间都被覆盖 
              numcover[num] = 1;    //并集的独立区间数目
         }else if( r > l+1 ){               //内结点
               len[num] = len[num<<1]+len[num<<1|1];
               leftcover[num] = leftcover[num<<1];
               rightcover[num] = rightcover[num<<1|1];
               numcover[num] = numcover[num<<1]+numcover[num<<1|1] - leftcover[num<<1|1]*rightcover[num<<1];
         }else{                            //叶结点
               len[num] = 0;
               leftcover[num] = rightcover[num] = 0;
               numcover[num] = 0;
         }
    }
    //插入
    void Insert( int l , int r , int num ){
         if( node[num].l == l && r == node[num].r ){
             node[num].sum++;
         }else{
             if( node[num].mid >= r ){
                 Insert( l , r , num<<1 );   
             }else if( node[num].mid <= l ){
                   Insert( l , r , num<<1|1 );     
             }else{
        Insert( l , node[num].mid , num<<1 );
        Insert( node[num].mid , r , num<<1|1 );
       }
         } 
         Updata( node[num].l , node[num].r , num );
    }
    //删除
    void Delete( int l , int r , int num ){
         if( node[num].l == l && r == node[num].r ){
             node[num].sum--;
         }else{
             if( node[num].mid >= r ){
                 Delete( l , r , num<<1 );   
             }else if( node[num].mid <= l ){
                   Delete( l , r , num<<1|1 );     
             }else{
        Delete( l , node[num].mid , num<<1 );
        Delete( node[num].mid , r , num<<1|1 );    
       }
         }
         Updata( node[num].l , node[num].r , num );
    }

    int cmp( const void *a , const void *b ){
        struct In *c = ( In *)a;
        struct In *d = ( In *)b;
        return c->pos - d->pos;   
    }

    int intcmp( const void *a , const void *b ){
        return *( int *)a - *(int *)b;   
    }
    int main()
    {   
        int i , j , x1 , x2 , y1 , y2 ,cas, k = 0;
        scanf("%d",&cas);
        while( cas-- ){
              scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
              str[k].start = y1 , str[k].end = y2 , str[k].flag = true , str[k].pos = x1 , str2[k] = y1;
              k++;
              str[k].start = y1 , str[k].end = y2 , str[k].flag = false , str[k].pos = x2 , str2[k]= y2;
              k++;
        }
        qsort( str , k , sizeof(In) , cmp );
        qsort( str2 , k , sizeof(int) , intcmp );
        int l = 1;
        hash[str2[0]] = l;
        hash2[1] = str2[0];
        for( i = 1 ; i < k ; i++ ){
             if( str2[i] != str2[i-1] ){
                 l++;
                 hash[str2[i]] = l;   
                 hash2[l] = str2[i];
             }
        }
        B_Tree( 1 , l , 1 );
        int sum = 0 , ans = 0 , value = 0;
        for( i = 0 ; i < k-1 ; i++ ){
             if( str[i].flag ){
                 Insert( hash[str[i].start] , hash[str[i].end] , 1 );   
             }else{
                  Delete( hash[str[i].start] , hash[str[i].end] , 1 );      
             }
             ans += 2*( str[i+1].pos - str[i].pos )*numcover[1];
             ans += abs( len[1] - value );
             value = len[1];
        }
        Delete( hash[str[i].start] , hash[str[i].end] , 1 );
        ans += abs( len[1] - value );
        printf("%d\n",ans);
        return 0;   
    }

  • 相关阅读:
    02 Hibernate错题分析
    08章 分组查询、子查询、原生SQL
    NHibernate的基本使用
    NHibernate与IbatisNet的简单比较
    NHibernate从入门到精通系列(3)——第一个NHibernate应用程序
    NHibernate从入门到精通系列(2)——NHibernate环境与结构体系
    NHibernate从入门到精通系列(1)——NHibernate概括
    SQL字符串操作汇总
    SVN (TortioseSVN) 版本控制之忽略路径(如bin、obj、gen)
    SVN服务器搭建和使用(三)
  • 原文地址:https://www.cnblogs.com/cnjy/p/1577280.html
Copyright © 2011-2022 走看看