10 25T2 二維線段樹

2022-05-01 18:27:15 字數 3132 閱讀 3173

為了準備校慶慶典,學校招募了一些學生組成了乙個方陣,準備在慶典上演出。

這個方陣是乙個n*m的矩形,第i行第j列有一名學生,他有乙個能力值ai,j。

校長會定期檢查乙個p*q的方陣,詢問這個方陣的學生能力值之和,或是學生能力值的最大值,或是學生能力值的最小值。由於校長不喜歡乙個方陣長寬之比差太多,他每次詢問的方陣的長不會超過寬的兩倍。作為校慶籌辦組組長的你,應該迅速並準確的回答校長所問的問題。

第一行包含兩個整數n,m,表示這個方陣的兩條邊的長度。

接下來n行,每行m個數,表示每個學生的能力值。

接下來一行包含乙個整數q,表示校長的詢問數。

接下來q行,每行先乙個字串s,接下來4個整數x1,y1,x2,y2,保證x1≤x2,y1≤y2,設以第x1行y1列為左上角,第x2行y2列為右下角的方陣為p。(本題為0下標)

若字串內容為「sum」,請求出p中所有學生的能力值之和。

若字串內容為「max」,請求出p中所有學生的能力值的最大值。

若字串內容為「min」,請求出p中所有學生的能力值的最小值。

輸出總共q行,第i行的數為第i組詢問對應的答案ansi。

3 31 2 3

4 5 6

7 8 9

3sum 0 0 1 1

max 0 0 2 2

min 0 1 1 1129

2【樣例解釋】

對於第一組詢問,能力值之和為1+2+4+5=12。

對於第二組詢問,能力值最大的位置為第2行第2列。

對於第三組詢問,能力值最小的位置為第0行第1列。

【資料規模和約定】

對於40%的資料,n,m≤200,q≤200

對於60%的資料,n,m≤300,q≤100000

對於80%的資料,n,m≤500,q≤500000

對於100%的資料,n,m≤800,q≤500000,0≤aij≤3000,每個詢問的方陣的長不超過寬的兩倍。

二維線段樹的板子。。。emmmm(好難寫啊)

code:

1 #include2 #include3 #include

4#define lc (p<<1)

5#define rc (p<<1|1)

6#define n 3301

7#define max(i,j) i>j?i:j

8#define min(i,j) i9

using

namespace

std;

10const

int inf=0x3f3f3f3f;11

int max=0,min=9999999;12

intn,m;

13int g[801][801],sum[801][801

];14

struct

segy

20} t[n];

21int

up,down;

22void pushup(int

p) 26

void build(int p,int l,int

r) 32

int mid=l+r>>1;33

build(lc,l,mid);

34 build(rc,mid+1

,r);

35pushup(p);36}

37int query_max(int p,int ql,int

qr)

41int a1=0,a2=0;42

int mid=t[p].l+t[p].r>>1;43

if(ql<=mid)a1=query_max(lc,ql,qr);

44if(qr>mid)a2=query_max(rc,ql,qr);

45return a1>a2?a1:a2;46}

47int query_min(int p,int ql,int

qr)

51int a1=inf,a2=inf;

52int mid=t[p].l+t[p].r>>1;53

if(ql<=mid)a1=query_min(lc,ql,qr);

54if(qr>mid)a2=query_min(rc,ql,qr);

55return a1>a2?a2:a1;56}

57};

58struct

segx t[800*4

];62

void build(int p,int l,int

r) 71

int query_min(int p,int x1,int y1,int x2,int

y2)

75int a1=inf,a2=inf;

76int mid=t[p].l+t[p].r>>1;77

if(x1<=mid)a1=query_min(lc,x1,y1,x2,y2);

78if(x2>mid)a2=query_min(rc,x1,y1,x2,y2);

79return a1>a2?a2:a1;80}

81int query_max(int p,int x1,int y1,int x2,int

y2)

85int a1=0,a2=0;86

int mid=t[p].l+t[p].r>>1;87

if(x1<=mid)a1=query_max(lc,x1,y1,x2,y2);

88if(x2>mid)a2=query_max(rc,x1,y1,x2,y2);

89return a1a2:a1;90}

91long

long

read()

98while

(isdigit(c))

102return x*f;

103}

104int

main()

111}

112 build(1,1

,n);

113int

q;114 q=read();

115char opt[5

];116

while(q--)

124if(opt[1]=='a'

) 130

if(opt[1]=='i'

) 136

}137

return0;

138 }

over

二維線段樹

二維線段樹一般用樹套樹的方式實現,每個外層線段樹的節點對應一顆內層線段樹,整個線段樹存放在乙個二維陣列中。二維線段樹 poj2155 include include include include include include include include include include inc...

二維線段樹

二維線段樹矩陣區間查詢最大值 矩陣求和預處理後o 1 就能算出來,不用線段樹,除非有修改操作 先第一維在第二維,注意建樹有個順序問題,應該讓第一維度的先建完然後再建第二個維度 具體看 include include include using namespace std const int maxn...

二維線段樹

一維線段樹用來維護一維的空間,即乙個線段。二維線段樹用來維護二維的空間,即乙個矩形。二維線段樹的每個結點都是一棵一維線段樹,所以結構體陣列要開二維,再加上線段樹本身的性質,會占用很大記憶體,要儘量減少結構體內儲存的值的個數和長度,考慮到每個節點表示的線段的左右端點可以作為函式引數,所以不再儲存在結構...