对于多维的问题,第一种方法几乎不可能使用。因此我们可以仿照第二种方法。例如对于n维的问题。我们构造以(a1,a2,a3,….,an,b1,b2,b3,….,bn)为根的线段树,其中(a1,a2,a3….,an)表示的是左下角的坐标,(b1,b2,b3,….,bn)表示的是右上角的坐标。构造的时候用的就不是二分,四分了,而是2n分,构造出一棵2n叉树。结点的个数变为2n×(b1-a1)×(b2-a2)×………×(bn-an)。
…以上转载自xuemao大牛的论文
const int maxn = 1000*1000*1.5;
//2D line tree
struct node
{
short x1,y1,x2,y2; //(a,b)--(c,d)
float max;
int *ch;
};
node tree[maxn]; //空间:O(N*M * 2) //实际上,1.4*N*M就足够了
int tol;
void maketree(int x1,int y1,int x2,int y2) //时间:O(2*N*M) 空间:O(2*N*M)
{
tol++;
int k = tol;
tree[k].x1 = x1;
tree[k].y1 = y1;
tree[k].x2 = x2;
tree[k].y2 = y2;
tree[k].max = 0.0;
if(x1==x2 && y1 == y2) //c==d
{
tree[k].ch = 0;
return;
}
tree[k].ch = new int[4];
int midx = (x1+x2)/2;
int midy = (y1+y2)/2;
if(x1<=midx && y1 <= midy) //左下
{
tree[k].ch[0] = tol+1;
maketree(x1,y1,midx,midy);
}
else
tree[k].ch[0] = 0;
if(midx+1 <= x2 && midy+1 <= y2) //右上
{
tree[k].ch[1] = tol+1;
maketree(midx+1,midy+1,x2,y2);
}
else
tree[k].ch[1] = 0;
if(x1 <= midx && midy+1 <= y2) //左上
{
tree[k].ch[2] = tol+1;
maketree(x1,midy+1,midx,y2);
}
else
tree[k].ch[2] = 0;
if(midx+1 <= x2 && y1 <= midy) //右下
{
tree[k].ch[3] = tol+1;
maketree(midx+1,y1,x2,midy);
}
else
tree[k].ch[3] = 0;
}
//时间:O(logN)//N*N的矩形
void insert(int x,int y,int L,int k) //这里,针对插入的是一个矩形[x,y]--[x,y]..一个单位正方形
{
if(tree[k].x1 == tree[k].x2 && tree[k].y1 == tree[k].y2) //叶子结点 //
{
if(L > tree[k].max)
tree[k].max = L;
return;
}
int midx = (tree[k].x1+tree[k].x2)/2;
int midy = (tree[k].y1+tree[k].y2)/2;
if(x<=midx)
{
if(y<=midy)
insert(x,y,L,tree[k].ch[0]);
else
insert(x,y,L,tree[k].ch[2]);
}
else //x>midx
{
if(y<=midy)
insert(x,y,L,tree[k].ch[3]);
else
insert(x,y,L,tree[k].ch[1]);
}
float m = tree[tree[k].ch[0]].max;
for(int i=1; i<4; i++)
m = max(m,tree[tree[k].ch[i]].max);
tree[k].max = m;
}
inline bool corss(int x1,int y1,int x2,int y2,int k) //判断两矩形是否相交
{
int x3 = tree[k].x1;
int y3 = tree[k].y1;
int x4 = tree[k].x2;
int y4 = tree[k].y2;
if(y2 < y3 || y4 < y1 || x4 < x1 || x2 < x3)
return false;
else
return true;
}
//时间:O(logN)//N*N的矩形
float Query(int x1,int y1,int x2,int y2,int k)
{
if(corss(x1,y1,x2,y2,k) == false || tree[k].max == 0) //矩形不相交或 矩形内max==0 则直接返回0
return 0;
if(x1<=tree[k].x1 && y1<=tree[k].y1 && tree[k].x2 <= x2 && tree[k].y2 <= y2) //如果要查询的矩形覆盖了当前矩形..则返回当前矩形的max值
return tree[k].max;
int midx = (tree[k].x1+tree[k].x2)/2;
int midy = (tree[k].y1+tree[k].y2)/2;
float m[4] = {0,0,0,0};
for(int i=0; i<4; i++)
m[i] = Query(x1,y1,x2,y2,tree[k].ch[i]);
float mm = m[0];
for(int i=1; i<4; i++)
mm = max(mm,m[i]);
return mm;
}