為了準備校慶慶典,學校招募了一些學生組成了乙個方陣,準備在慶典上演出。
這個方陣是乙個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 #include4#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...
二維線段樹
一維線段樹用來維護一維的空間,即乙個線段。二維線段樹用來維護二維的空間,即乙個矩形。二維線段樹的每個結點都是一棵一維線段樹,所以結構體陣列要開二維,再加上線段樹本身的性質,會占用很大記憶體,要儘量減少結構體內儲存的值的個數和長度,考慮到每個節點表示的線段的左右端點可以作為函式引數,所以不再儲存在結構...