POJ1769

摘要:第一個線段樹,^_^

注意別排序哦,按題目要求順序已經固定了,所以不可以貪心。

 

#include <iostream>
#include <cassert>
#include <stdio.h>
using namespace std;

typedef struct Node{
    int left;
    int right;
    int minstep;
    Node *left_child;
    Node *right_child;
    void Construct(int, int);
    void Insert(int, int);
    int GetRank(int, int);       
}Node;

const int size = 50000;
Node stree[size*2+2];
Node *root = &stree[0];
int len = 0;


void Node::Construct(int l, int r)
{
    //cout << "Construct Node:" << len-1 << endl;
    left = l;
    right = r;
    minstep = 999999;
    if( l == r ){
        left_child == NULL;
        right_child == NULL;
        return;
    }
    int mid = (l + r) >> 1;
    //cout << l << "/t" << r << "/t" << mid << endl;
    //assert( len < 200 );
    left_child = &stree[len++];
    right_child = &stree[len++];

    assert(left_child && right_child);

    left_child->Construct(l, mid);
    right_child->Construct(mid+1, r);
}


void Node::Insert(int r, int s)
{
       
    if(right < r || left > r){
        return;
    }   
    minstep = min(minstep, s);
    if(left == right){
        return;
    }   
    int mid = (left + right) >> 1;
    assert(left_child && right_child);   
    if( r <= mid ){
        left_child->Insert(r, s);
    }else{
        right_child->Insert(r, s);
    }
}

int Node::GetRank(int l, int r)
{
    if( l==left && r==right){
        return minstep;
    }
    int mid = (left + right) >> 1;
   
    //cout << l << "/t" << left << endl;
    //cout << r << "/t" << right << endl;

    assert(left_child && right_child);
   
    if( r <= mid ){
        return left_child->GetRank(l, r);
    }   
    if( l > mid ){
        return right_child->GetRank(l, r);
    }
    int ret1, ret2;
    ret1 = left_child->GetRank(l, mid);
    ret2 = right_child->GetRank(mid+1, r);
   
    return ret1<ret2 ? ret1 : ret2;
}


int main()
{
    int n;
    scanf("%d", &n);
    len = 1;
    root->Construct(1, n);   

    int m;
    scanf("%d", &m);
    root->Insert(1, 0);
   
    for(int i=1; i<=m; i++){
        int left, right;
        scanf("%d", &left);
        scanf("%d", &right);
        if( left < right ){
            int step = root->GetRank(left, right-1);
            root->Insert(right, step + 1);       
        }
    }   
   
    int min_step = root->GetRank(n, n);

    cout << min_step << endl;
    return 0;       
}

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