| Description |
| Input |
输入数据共
n
+
1
n+1
n+1行。第一行一个整数
n
n
n表示共需要处理
n
n
n次内存分配。然后是
n
n
n行数据,每行的格式为
a
i
b
i
a_ib_i
aibi表示申请区间为
[
a
i
,
b
i
]
[a_i,b_i]
[ai,bi]
数据规模:
n
≤
1
,
000
,
000
;
0
<
a
i
≤
b
i
≤
2
30
n\leq 1,000,000;0
| Output |

区间树查找,插入的时间复杂度都为
lg
n
\lg n
lgn,所以不会超时
#include
#define BLACK 0
#define RED 1
#define ll long long int
using namespace std;
const int N = 1e6;
int n;
typedef struct interval{
ll low;
ll high;
}interval;
interval arr[N];//区间数组
typedef struct Node{
ll key;
bool color;
Node *parent;
Node *left;
Node *right;
interval inte; //区间信息
ll max; //子树中端点最大值
}Node;
typedef struct IntervalTree{
Node *root;
}IntervalTree;
//NIL结点
interval Nil_interval={-1,-1};
Node NILL={-1,BLACK,NULL,NULL,NULL,Nil_interval,-1};
Node *NIL=&NILL;
Node *Search(IntervalTree *T,interval i)
{//查找结点
Node *x=T->root;
while(x!=NIL && (i.high<x->inte.low||i.low>x->inte.high))//a.high < b.low || a.low > b.high
{
if(x->left !=NIL && x->left->max>= i.low)
x=x->left;
else
x=x->right;
}
return x;
}
void LeftRotate(IntervalTree *T,Node *x)
{//左旋操作
Node *y=x->right; //取x的右孩子
x->right=y->left; //y的左子树变成x的右子树
if(y->left!=NIL)
y->left->parent=x;
y->parent=x->parent; //连接x的父结点到y
if(x->parent == NIL)
T->root=y;
else if(x==x->parent->left)
x->parent->left=y;
else
x->parent->right=y;
y->left=x; //x放到y的左子树
x->parent=y;
//维护最大值信息
y->max=x->max;
x->max=max(x->inte.high,max(x->left->max,x->right->max));
}
void RightRotate(IntervalTree *T,Node *x)
{//与左旋类似
Node *y=x->left;
x->left=y->right;
if(y->right !=NIL)
y->right->parent=x;
y->parent=x->parent;
if(x->parent == NIL)
T->root=y;
else if(x == x->parent->left)
x->parent->left=y;
else
x->parent->right=y;
y->right=x;
x->parent=y;
y->max=x->max;
x->max=max(x->inte.high,max(x->left->max,x->right->max));
}
void InsertFixup(IntervalTree *T,Node *z)
{
while(z->parent->color==RED)
{
if(z->parent == z->parent->parent->left)
{
Node *y=z->parent->parent->right;
if(y->color==RED)
{
z->parent->color=BLACK;
y->color=BLACK;
z->parent->parent->color=RED;
z=z->parent->parent;
}
else
{
if(z==z->parent->right)
{
/*这里是第二种情况*/
z=z->parent;
LeftRotate(T,z);
}
/*这里是第三种情况*/
z->parent->color=BLACK;
z->parent->parent->color=RED;
RightRotate(T,z->parent->parent);
}
}
else
{ /*第四种种情况*/
Node *y=z->parent->parent->left;
if(y->color==RED)
{
z->parent->color==BLACK;
y->color=BLACK;
z->parent->parent->color=RED;
z=z->parent->parent;
}
else
{
if(z==z->parent->left)
{
z=z->parent;
RightRotate(T,z);
}
z->parent->color=BLACK;
z->parent->parent->color=RED;
LeftRotate(T,z->parent->parent);
}
}
}
T->root->color=BLACK; //根结点变成黑色
}
void Insert(IntervalTree *T,interval inte)
{
Node *z=new Node();
z->key=inte.low;
z->max=inte.high;
z->inte=inte;
z->color =RED;
z->parent=NIL;
z->left=NIL;
z->right=NIL;
Node *y=NIL; //y是x的父结点
Node *x=T->root;
while(x != NIL)
{
x->max=max(x->max,z->max); //维护最大端点值
y=x;
if(z->key < x->key)
x=x->left;
else
x=x->right;
}
z->parent=y;
if(y==NIL)
T->root=z;
else if(z->key < y->key)
y->left=z;
else
y->right =z;
InsertFixup(T,z);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lld %lld",&arr[i].low,&arr[i].high);
IntervalTree *T=new IntervalTree();
T->root=NIL;
for(int i=0;i<n;i++)
{
Node *temp=Search(T,arr[i]);
if(temp==NIL)
{
cout<<0<<endl;
Insert(T,arr[i]);
}
else
cout<<-1<<endl;
}
return 0;
}