zoj 2589 Matrix Searching 二维线段树

题目链接

给一个n*n的矩阵, 给q个查询, 每次给出x1, y1, x2, y2, 求这个矩阵中的最小值。

代码基本上和上一题相同...

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define pb(x) push_back(x)
  4 #define ll long long
  5 #define mk(x, y) make_pair(x, y)
  6 #define lson l, m, rt<<1
  7 #define mem(a) memset(a, 0, sizeof(a))
  8 #define rson m+1, r, rt<<1|1
  9 #define mem1(a) memset(a, -1, sizeof(a))
 10 #define mem2(a) memset(a, 0x3f, sizeof(a))
 11 #define rep(i, a, n) for(int i = a; i<n; i++)
 12 #define ull unsigned long long
 13 typedef pair<int, int> pll;
 14 const double PI = acos(-1.0);
 15 const double eps = 1e-8;
 16 const int mod = 1e9+7;
 17 const int inf = 1061109567;
 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
 19 const int maxn = 305;
 20 int maxx[maxn<<2][maxn<<2], minn[maxn<<2][maxn<<2], max_ans, min_ans, n;
 21 void pushUp(int pos, int rt) {
 22     minn[pos][rt] = min(minn[pos][rt<<1], minn[pos][rt<<1|1]);
 23 }
 24 void sub_build(int sign, int pos, int l, int r, int rt) {
 25     if(l == r) {
 26         if(!sign) {
 27             scanf("%d", &minn[pos][rt]);
 28         } else {
 29             minn[pos][rt] = min(minn[pos<<1][rt], minn[pos<<1|1][rt]);
 30         }
 31         return ;
 32     }
 33     int m = l+r>>1;
 34     sub_build(sign, pos, lson);
 35     sub_build(sign, pos, rson);
 36     pushUp(pos, rt);
 37 }
 38 void build(int l, int r, int rt) {
 39     if(l == r) {
 40         sub_build(0, rt, 1, n, 1);
 41         return ;
 42     }
 43     int m = l+r>>1;
 44     build(lson);
 45     build(rson);
 46     sub_build(1, rt, 1, n, 1);
 47 }
 48 void sub_update(int sign, int pos, int y, int l, int r, int rt, int val) {
 49     if(l == r) {
 50         if(!sign) {
 51             minn[pos][rt] = val;
 52         } else {
 53             minn[pos][rt] = min(minn[pos<<1][rt], minn[pos<<1|1][rt]);
 54         }
 55         return ;
 56     }
 57     int m = l+r>>1;
 58     if(y<=m)
 59         sub_update(sign, pos, y, lson, val);
 60     else
 61         sub_update(sign, pos, y, rson, val);
 62     pushUp(pos, rt);
 63 }
 64 void update(int x, int y, int l, int r, int rt, int val) {
 65     if(l == r) {
 66         sub_update(0, rt, y, 1, n, 1, val);
 67         return ;
 68     }
 69     int m = l+r>>1;
 70     if(x<=m)
 71         update(x, y, lson, val);
 72     else
 73         update(x, y, rson, val);
 74     sub_update(1, rt, y, 1, n, 1, val);
 75 }
 76 void sub_query(int pos, int L, int R, int l, int r, int rt) {
 77     if(L<=l&&R>=r) {
 78         max_ans = max(max_ans, maxx[pos][rt]);
 79         min_ans = min(min_ans, minn[pos][rt]);
 80         return ;
 81     }
 82     int m = l+r>>1;
 83     if(L<=m)
 84         sub_query(pos, L, R, lson);
 85     if(R>m)
 86         sub_query(pos, L, R, rson);
 87 }
 88 void query(int LX, int RX, int LY, int RY, int l, int r, int rt) {
 89     if(LX<=l&&RX>=r) {
 90         sub_query(rt, LY, RY, 1, n, 1);
 91         return ;
 92     }
 93     int m = l+r>>1;
 94     if(LX<=m)
 95         query(LX, RX, LY, RY, lson);
 96     if(RX>m)
 97         query(LX, RX, LY, RY, rson);
 98 }
 99 int main()
100 {
101     int t, x, y, l, q, cnt = 1;
102     cin>>t;
103     while (t--) {
104         scanf("%d", &n);
105         build(1, n, 1);
106         cin>>q;
107         while(q--) {
108             int LX, RX, LY, RY;
109             scanf("%d%d%d%d", &LX, &LY, &RX, &RY);
110             min_ans = inf, max_ans = 0;
111             query(LX , RX, LY, RY, 1, n, 1);
112             printf("%d\n", min_ans);
113         }
114     }
115 }
时间: 2024-11-06 06:59:05

zoj 2589 Matrix Searching 二维线段树的相关文章

ZOJ 1859 Matrix Searching(二维线段树)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1859 Matrix Searching Time Limit: 10 Seconds      Memory Limit: 32768 KB Given an n*n matrix A, whose entries Ai,j are integer numbers ( 1 <= i <= n, 1 <= j <= n ). An operation FIND t

[POJ2155] Matrix(二维线段树,树套树)

题目链接:http://poj.org/problem?id=2155 题意:给一个01矩阵,两个操作,翻转:子矩阵里每一个数都由0变1,1变0. 查询:查询某一点是0还是1. 一直以为二维线段树就是开一个线段树数组的我- 这题暴力更新每一个小矩形,翻转就+1,最后看看某点的奇偶. 写屎了,特别注意的是在外层查询的时候要先把当前层的内层query掉,接着再向下扩展.这样外层就不用lazy啦 1 #include <algorithm> 2 #include <iostream> 3

POJ 2155 Matrix【二维线段树】

题目大意:给你一个全是0的N*N矩阵,每次有两种操作:1将矩阵中一个子矩阵置反,2.查询某个点是0还是1 思路:裸的二维线段树 #include<iostream>#include<cstdio>#include <math.h>#include<algorithm>#include<string.h>#include<queue>#define MOD 1000003#define maxn 4009#define LL long

ZOJ 2859 二维线段树

思路:自己写的第二发二维线段树1A,哈哈,看来对二维的push操作比较了解了:但是还没遇到在两个线段树中同时进行push操作的,其实这题我是想在x维和y维同时进行push操作的,但是想了好久不会,然后看到这题又给出10秒,然后想想在x维线段直接单点查询肯定也过了,然后在第二维就只有pushup操作,在第一维线段树没有pushup操作.要是在第一维也有pushup操作的话,那就不用单点查询那么慢了.不过也A了,想找题即在二维同时进行pushup和pushdown操作的. #include<iost

POJ 2155 Matrix (二维线段树)

http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18143   Accepted: 6813 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. I

POJ2155 Matrix二维线段树经典题

题目链接 二维树状数组 1 #include<iostream> 2 #include<math.h> 3 #include<algorithm> 4 #include<stdlib.h> 5 using namespace std; 6 #define ll long long 7 #define re(i,n) for(int i=0;i<n;i++) 8 const int maxn = 1007; 9 int c[maxn][maxn]; 10

POJ 2155 Matrix 二维线段树+标记永久化?

题意:链接 方法:二维线段树+标记永久化 解析:题意是比较明朗的,算一下内存发现4000^2也是可以接受的,于是就开始yy二维线段树? 对于第一层x的线段树,每个节点开一整棵y线段树. 用个二维数组就实现了? 不过发现个问题啊,这题怎么pushdown啊,标记传不下去啊.如果给x打个标记那么怎么知道y传那段啊? 于是就学了新的东西?标记永久化. 本题是单点查询嘛,标记永久化就应该是把相应的区间直接异或,不用往下传?那查询的时候怎么办呢?只需要在查询的时候把所有路过该点的区间都异或起来就OK了.貌

poj2155 Matrix 二维线段树

二维线段树区间更新和单点查询,由于二维线段树不能传递标记,所以区间更新和一维不太一样,需要用到被更新的值以及更新操作的一些性质,还有要注意对query的影响. 这里操作是翻转,而且是单点查询,所以就直接在矩形块内更新,不把标记传递下去,查询的时候做一下微调,把所有经过的路径的标记都判断一遍,看是否需要翻转,这样就解决了这道题. 上一道是单点更新和区间求和,当然就不用标记了,把所有的第一维的第二层的y点全部更新,查询的时候不用查到最底层也能查到了. 二维线段树还是比较灵活,但这已经是最简单的树套树

POJ1195 Mobile phones 【二维线段树】

Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14291   Accepted: 6644 Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The