摘要:第一個線段樹,^_^
注意別排序哦,按題目要求順序已經固定了,所以不可以貪心。
#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;
}