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;   
}

原文地址:https://www.cnblogs.com/cnjy/p/1577280.html