2-D搜索树
Description
根据给定的输入数据建立并维护一棵2-D搜索树,依次给出m条记录,每条记录包含Key1和Key2两个值,按顺序依次将这些记录插入2-D搜索树中,在给出m条记录的过程中,无规律地穿插有n条查询指令,包含Low1、High1、Low2和High2四个值,遇到查询指令时,搜索并输出到目前为止2-D搜索树中满足Low1<=Key1<=High1且Low2<=Key2<=High2的记录总数(只需输出数量,无需输出每条记录,因此本题与每个结点的value值无关,无需提供value值)。
Input Description
输入数据有(m+n+1)行,第一行有两个数m和n,分别表示插入结点总数和查询总次数。之后有m行插入指令和n行查询指令,二者无规律穿插在一起。插入指令以”0”开头,各数以空格隔开,格式为:0 Key1 Key2,表示向2-D搜索树中插入含有Key1和Key2的一条记录;查询指令以”1”开头,以空格隔开,格式为:1 Low1 High1 Low2 High2,表示查询到目前为止这棵树中满足Low1<=Key1<=High1且Low2<=Key2<=High2的记录总数,并逐行输出。
以上输入的所有数据均为int类型。其中0小于m小于100k,0小于n小于100k,Key1和Key2以及查询区间边界则可以为int范围内任意整数。
Input Sample
7 2
0 7 1
0 4 3
0 2 9
0 6 6
1 2 8 3 7
0 -1 5
0 6 3
0 5 3
1 1 6 2 3
Output Sample
2
3
Hint
参照二叉搜索树的实现,每个结点改为两个key值,并按照奇数层和偶数层来决定根据key1还是key2分叉(根结点为第1层,即奇数层)。可以在每个结点增加变量layer,用来判断此结点位于奇数层还是偶数层。
如何得到符合查询条件的记录个数?这与遍历整个二叉树有何区别?与在二叉搜索树中查找某个特定值又有何区别?请尽量采用高效的做法。
Idea
每添加一个结点相当于把xy平面分成两块,越分越小。最后求一个矩形框中点的个数。
Code
#include<iostream>
using namespace std;
struct Node{
int key1,key2;
int layer;
Node *lc,*rc;
};
void Insert(Node *&BT,int item1,int item2,int Layer){
if(BT==NULL){
Node *p=new Node;
p->key1=item1;
p->key2=item2;
p->layer=Layer;
p->lc=p->rc=NULL;
BT=p;
}
else if(Layer %2==1){
if(item1 <= BT->key1)
Insert(BT->lc,item1,item2,Layer+1);
else
Insert(BT->rc,item1,item2,Layer+1);
}
else if(Layer %2==0){
if(item2 <= BT->key2)
Insert(BT->lc,item1,item2,Layer+1);
else
Insert(BT->rc,item1,item2,Layer+1);
}
}
void preOrder(Node *BT){
if(BT!=NULL){
cout<<BT->key1<<","<<BT->key2<<" ";
preOrder(BT->lc);
preOrder(BT->rc);
}
}
int Seek(Node *BT,int low1,int high1,int low2,int high2){
int count=0;
if(BT==NULL)
return 0;
else{
if(BT->layer %2==1){
if(BT->key1 > high1)
count+=Seek(BT->lc,low1,high1,low2,high2);
else if(BT->key1 < low1)
count+=Seek(BT->rc,low1,high1,low2,high2);
else if(BT->key2 >= low2 && BT->key2 <=high2){
count++;
count+=Seek(BT->lc,low1,high1,low2,high2);
count+=Seek(BT->rc,low1,high1,low2,high2);
}
else{
count+=Seek(BT->lc,low1,high1,low2,high2);
count+=Seek(BT->rc,low1,high1,low2,high2);
}
}
if(BT->layer %2==0){
if(BT->key2 > high2)
count+=Seek(BT->lc,low1,high1,low2,high2);
else if(BT->key2 < low2)
count+=Seek(BT->rc,low1,high1,low2,high2);
else if(BT->key1 >=low1 && BT->key1 <=high1){
count++;
count+=Seek(BT->lc,low1,high1,low2,high2);
count+=Seek(BT->rc,low1,high1,low2,high2);
}
else{
count+=Seek(BT->lc,low1,high1,low2,high2);
count+=Seek(BT->rc,low1,high1,low2,high2);
}
}
}
return count;
}
int main(){
int m,n;
cin>>m>>n;
int input[4];
int *output=new int[n];
int k=0;
Node *BT=NULL;
for(int i=0;i<m+n;i++){
int flag;
cin>>flag;
if(flag==0){
cin>>input[0]>>input[1];
Insert(BT,input[0],input[1],1);
}
else if(flag==1){
for(int j=0;j<4;j++)
cin>>input[j];
output[k]=Seek(BT,input[0],input[1],input[2],
input[3]);
k++;
}
}
for(int i=0;i<n;i++)
cout<<output[i]<<endl;
delete[] output;
return 0;
}