POJ2528

 摘要:第二個線段樹

#include <iostream>
#include <string.h>
#include <algorithm>
#include <map>
#include <vector>
#include <utility>
#include <cassert>

using namespace std;

typedef struct Node{
    int left;
    int right;
    int poster;
    Node * left_child;
    Node * right_child;
    void Insert(int, int, int);
    void Calculate();
    void Construct(int, int);   
}Node;
const int size = 10000;

Node stree[6 * size ];
Node *root = &stree[0];

int len = 0;

int wall[2*size+1] = {0};
int x_index[2*size+1] = {0};
int poster[size+1] = {0};

void Node::Construct(int l, int r)
{
    left = l;
    right = r;
    poster = 0;
    if(l+1 == r){
        left_child = NULL;
        right_child = NULL;
        return;
    }

    int mid = (l + r) >> 1;
    left_child = &stree[len++];
    right_child = &stree[len++];
   
    left_child->Construct(l, mid);
    right_child->Construct(mid, r);
}

void Node::Insert(int l, int r, int p)
{
    if( p == poster ){
        return;
    }
    if( l==left && r==right){
        poster = p;
        return;
    }
    if(l >= r){
        return;
    }   
   
    if(poster!=-1){
        left_child->poster = poster;
        right_child->poster = poster;
    }
    poster = -1;

    int mid = (left + right) >> 1;
    if( r <= mid ){
        left_child->Insert(l, r, p);
        return;
    }
    if( l >= mid ){
        right_child->Insert(l, r, p);
        return;
    }
    left_child->Insert(l, mid, p);
    right_child->Insert(mid, r, p);
}

void Node::Calculate()
{
    if( poster == 0 ){
        return;
    }
   
    if( poster != -1){
        for(int i=left; i<right; i++){
            wall[i] = poster;
        }
        return;
    }

    left_child->Calculate();
    right_child->Calculate();
}
int findIndex(int value, vector<int>  & data)
{
    int left = 0;
    int right = data.size()-1;
    int mid = 0;;
    while( left <= right ){
        mid = (left + right) >> 1;
        if( data.at(mid) == value){
            return mid;
        }   
        if( data.at(mid) > value ){
            right = mid-1;
        }else{
            left = mid+1;
        }
    }   
   
    return -1;
}

int main()
{
    int n;
    cin >> n;
   
    for(int i=1; i<=n; i++){
        len = 1;
        root->Construct(1, 2 * size + 1);

        memset(wall, 0, sizeof(wall));
        memset(poster, 0, sizeof(poster));
        int m;
        cin >> m;
   
        vector<int> buf;
        vector<pair<int, int> > data;   
       
        for(int j=1; j<=m; j++){
            int left, right;
            cin >> left >> right;   
            data.push_back( make_pair(left, right+1) );
            buf.push_back(left);
            buf.push_back(right+1);
        }

        sort(buf.begin(), buf.end());
        vector<int>::iterator erase_iter = unique(buf.begin(), buf.end()); buf.erase(erase_iter, buf.end());
        buf.erase(erase_iter, buf.end());
       
        for(vector<pair<int, int> >::iterator iter=data.begin(); iter!=data.end(); iter++){
            int left = findIndex(iter->first, buf) + 1;
            int right = findIndex(iter->second, buf) + 1;
            assert(left!=0 && right!=0);
            root->Insert(left, right, iter-data.begin()+1);   
        }
       
        root->Calculate();
       
        for(int j=1; j<=size; j++){
            if(wall[j] != -1 && wall[j] != 0){
                poster[wall[j]] = 1;
            }   
        }

        int total_view = 0;
        for(int j=1; j<=m; j++){
            total_view += poster[j];       
        }
        cout << total_view << endl;   
    }
   
    return 0;
}

發佈了63 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章