算法基础习题—内存分配(区间树实现)

Posted 之墨_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法基础习题—内存分配(区间树实现)相关的知识,希望对你有一定的参考价值。

算法基础习题—内存分配(区间树实现)

Description
C语言中需要申请一块连续的内存时需要使用malloc等函数。如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。现在小明决定实现一个类似malloc的内存分配系统,具体来说,他需要连续处理若干申请内存的请求,这个请求用一个闭区间$[a_i..b_i]$来表示。当这个区间和当前已被申请的内存产生重叠时,则返回内存分配失败的信息。否则返回内存分配成功,并将该区间标记为已被占用。假设初始状态下内存均未被占用,管理的内存地址范围为$0-1GB(0-2^30)$。
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<a_i\\leq b_i \\leq 2^30 n1,000,000;0<aibi230

Output
输出共n行。 对于每行内存分配的申请,若申请成功则输出一行0,若申请失败则输出一行-1

区间树查找,插入的时间复杂度都为 lg ⁡ n \\lg n lgn,所以不会超时

#include<bits/stdc++.h>
#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;
	
 

以上是关于算法基础习题—内存分配(区间树实现)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法(周鹏-未出版)-第六章 树-习题

UOJ#228基础数据结构练习题 线段树

uoj#228. 基础数据结构练习题(线段树)

基础算法——二分(原理细节与习题归纳整理)

基础练习区间DPcodevs1090 加分二叉树题解

树链剖分