zoj 2859 二维线段树 插点求线
2015-08-18 10:22
477 查看
题意:….
思路:二维线段树。。 理解好Modify操作
思路:二维线段树。。 理解好Modify操作
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int maxn = 320; const int INF = 0x3ff3f3f; int locy[maxn],locx[maxn]; struct nodey { int l, r; int Max,Min; }; int n,b,k; struct nodex { int l,r; nodey sty[maxn*4]; void build(int i, int _l, int _r) { sty[i].l = _l; sty[i].r = _r; sty[i].Max = -INF; sty[i].Min = INF; if(_l == _r) { locy[_l] = i; return; } int mid = (_l+_r)/2; build(i<<1, _l, mid); build(i<<1|1, mid+1, _r); } int queryMin(int i, int _l, int _r) { if(sty[i].l == _l && sty[i].r == _r) return sty[i].Min; int mid = (sty[i].l + sty[i].r)/2; if(_r<=mid) return queryMin(i<<1, _l, _r); else if(_l>mid) return queryMin(i<<1|1, _l, _r); else { int t1 = queryMin(i<<1, _l, mid); int t2 = queryMin(i<<1|1, mid+1, _r); return min(t1,t2); } } int queryMax(int i, int _l, int _r) { if(sty[i].l == _l && sty[i].r == _r) return sty[i].Max; int mid = (sty[i].l + sty[i].r)>>1; if(_r<=mid) return queryMax(i<<1, _l, _r); else if(_l>mid) return queryMax(i<<1|1, _l, _r); else { int t1 = queryMax(i<<1, _l, mid); int t2 = queryMax(i<<1|1, mid+1, _r); return max(t1, t2); } } }stx[maxn*4]; void build(int rt, int _l, int _r) { stx[rt].l = _l; stx[rt].r = _r; stx[rt].build(1, 1, n); if(_l == _r) { locx[_l] = rt; return; } int mid = (_l + _r)>>1; build(rt<<1, _l, mid); build(rt<<1|1, mid+1, _r); } int queryMin(int i, int x1, int y1, int x2, int y2) { if(stx[i].l == x1&&stx[i].r == x2) return stx[i].queryMin(1, y1, y2); int mid = (stx[i].l+stx[i].r)>>1; if(x2<=mid) return queryMin(i<<1, x1, y1, x2, y2); else if(x1>mid) return queryMin(i<<1|1, x1, y1, x2, y2); else { int a = queryMin(i<<1, x1, y1, mid, y2); int b = queryMin(i<<1|1, mid+1, y1, x2, y2); return min(a, b); } } int queryMax(int i, int x1, int y1, int x2, int y2) { if(stx[i].l == x1&&stx[i].r == x2) return stx[i].queryMax(1, y1, y2); int mid = (stx[i].l+stx[i].r)>>1; if(x2<=mid) return queryMax(i<<1, x1, y1, x2, y2); else if(x1>mid) return queryMax(i<<1|1, x1, y1, x2, y2); else { int a = queryMax(i<<1, x1, y1, mid, y2); int b = queryMax(i<<1|1, mid+1, y1, x2, y2); return max(a, b); } } void Modify(int x, int y, int val) { int tx = locx[x]; int ty = locy[y]; stx[tx].sty[ty].Min = stx[tx].sty[ty].Max = val; for(int i=tx;i;i>>=1) for(int j=ty; j; j>>=1) { if(i == tx&& j == ty) continue; if(j == ty) { stx[i].sty[j].Min = min(stx[i<<1].sty[j].Min, stx[i<<1|1].sty[j].Min); stx[i].sty[j].Max = max(stx[i<<1].sty[j].Max, stx[i<<1|1].sty[j].Max); } else { stx[i].sty[j].Min = min(stx[i].sty[j<<1].Min,stx[i].sty[(j<<1)|1].Min); stx[i].sty[j].Max = max(stx[i].sty[j<<1].Max,stx[i].sty[(j<<1)|1].Max); } } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T; scanf("%d",&T); int iCase = 0; while(T--) { iCase++; scanf("%d",&n); build(1,1,n); for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) { int a; scanf("%d",&a); Modify(i,j,a); } int q; int x1,y1,x2,y2; scanf("%d",&q); while(q--) { scanf("%d%d%d%d",&x1,&y1,&x2, &y2); int Min = queryMin(1,x1,y1,x2,y2); printf("%d\n",Min); } } return 0; }
相关文章推荐
- 线段树题集
- hdu1754
- HDU1394
- 敌兵布阵 (1)
- I Hate It (1)
- LCIS (2)
- A Simple Problem with Integers (2)
- Mayor's posters (3)
- Buy Tickets (3)
- 线段树
- UVA - 12532 Interval Product
- POJ 3264 Balanced Lineup
- hdu 1542 求矩形并的面积
- 关于数据结构之线段树
- poj 3225 关于集合运算
- poj 2352
- hdu1166敌兵布阵(线段树点修改)
- POJ 2352 Stars 线段树 pascal
- hdu 1698 Just A Hook 线段树的一道题
- HDU 1754 I Hate It