poj 2155 二維線段樹

2022-05-04 10:12:08 字數 1749 閱讀 3808

在乙個二維陣列中,每次對乙個矩形內所有資料進行取反操作,並實時詢問某一位置的值。

一般線段樹只支援對一維資料進行更新和查詢,但是這題給的是二維資料啊!

這裡就需要用到二維線段樹了,即樹套樹,外層線段樹的每個結點裡面都有一顆線段樹。

在實現二維線段樹的時候,一開始用加build函式的方式,記錄每個結點左右孩子的編號,但超記憶體了,所以直接用二維陣列表示二維線段樹,左右孩子編號通過計算得到:設父親結點為o,左孩子結點就是o*2,右孩子結點就是o*2+1。

這樣既省去了建樹的時間,也省去了儲存左右孩子編號的空間。但是要注意的是這時候陣列要開到maxn*4,而平時只需要開到maxn*2,因為這裡的計算左右孩子結點的方法無疑是浪費了一些空間的。

#include#include

#include

#include

using

namespace

std;

const

int maxn = 1002

;int

n;bool tree[maxn*4][maxn*4

];void updy(bool *tree,int cur,int curl,int curr,int l,int

r)

int mid = (curl+curr)>>1

;

if(l>=mid+1) updy(tree,cur*2+1,mid+1

,curr,l,r);

else

if(r<=mid) updy(tree,cur*2

,curl,mid,l,r);

else

}void upd(int cur,int curl,int curr,int l,int r,int y1,int

y2)

int mid = (curl+curr)>>1

;

if(l>=mid+1) upd(cur*2+1,mid+1

,curr,l,r,y1,y2);

else

if(r<=mid) upd(cur*2

,curl,mid,l,r,y1,y2);

else

}bool queryy(bool *tree,int cur,int curl,int curr,int

l)

int mid = (curl+curr)>>1

;

if(l>=mid+1) return tree[cur]^queryy(tree,cur*2+1,mid+1

,curr,l);

else

if(l<=mid) return tree[cur]^queryy(tree,cur*2

,curl,mid,l);

}bool query(int cur,int curl,int curr,int l,int

r)

int mid = (curl+curr)>>1

;

if(l>=mid+1) return queryy(tree[cur],1,1,n,r)^query(cur*2+1,mid+1

,curr,l,r);

else

if(l<=mid) return queryy(tree[cur],1,1,n,r)^query(cur*2

,curl,mid,l,r);

}int

main()

else

}puts(

"");

}}

poj2155 二維線段樹

題目大意 給定初始n n矩陣,所有數都是0,然後有 c 操作 對左上角 x1,y1 到右下角 x2,y2 的矩陣中所有數取非,即0變1,或1變0 還有 q 操作 查詢點 x,y 的值並輸出。思路 構造乙個線段樹,每個結點還是線段樹,外圍線段樹表示x方向,子線段樹表示y方向。查詢時對結點 x,y 所在...

POJ 2155 二維線段樹

題意 給乙個01矩陣,每次可以進行操作將 x1,x2,y1,y2 內的所有元素0變1 1變0。也可以進行詢問,詢問某乙個格仔的0和1。輸出詢問。思路 二維線段樹版題,稍微轉化一下記錄查詢乙個點時它所經過的路徑上經過偶數次修改就為0,奇數次為1。線段樹有兩種寫法,第一種把下標放在樹的結點中,時不時會m...

二維線段樹 poj 2155

題意 t組樣例 輸入 n,m,表示n n的矩陣進行m次操作 c 輸入兩個座標 組成的矩形 進行取反操作 q 對輸的座標位置輸入其值。思路 一開始想的是用1000 表示x軸 個線段樹 對每段y進行操作 來記錄,也是二維的 第一維暴力 第二維線段樹 結果ti 原來還有二維線段樹,每個對應的節點都有一顆線...