码迷,mamicode.com
首页 > 其他好文 > 详细

UVALive 6709 - Mosaic 二维线段树

时间:2015-12-07 12:32:53      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

题目链接

给一个n*n的方格, 每个方格有值。 每次询问, 给出三个数x, y, l, 求出以x, y为中心的边长为l的正方形内的最大值与最小值, 输出(maxx+minn)/2, 并将x, y这个格子的值改为(maxx+minn)/2。题目保证l为奇数。

二维线段树的单点更新, 区间查询。

  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 = 805;
 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     maxx[pos][rt] = max(maxx[pos][rt<<1], maxx[pos][rt<<1|1]);
 23     minn[pos][rt] = min(minn[pos][rt<<1], minn[pos][rt<<1|1]);
 24 }
 25 void sub_build(int sign, int pos, int l, int r, int rt) {
 26     if(l == r) {
 27         if(!sign) {
 28             scanf("%d", &maxx[pos][rt]);
 29             minn[pos][rt] = maxx[pos][rt];
 30         } else {
 31             minn[pos][rt] = min(minn[pos<<1][rt], minn[pos<<1|1][rt]);
 32             maxx[pos][rt] = max(maxx[pos<<1][rt], maxx[pos<<1|1][rt]);
 33         }
 34         return ;
 35     }
 36     int m = l+r>>1;
 37     sub_build(sign, pos, lson);
 38     sub_build(sign, pos, rson);
 39     pushUp(pos, rt);
 40 }
 41 void build(int l, int r, int rt) {
 42     if(l == r) {
 43         sub_build(0, rt, 1, n, 1);
 44         return ;
 45     }
 46     int m = l+r>>1;
 47     build(lson);
 48     build(rson);
 49     sub_build(1, rt, 1, n, 1);
 50 }
 51 void sub_update(int sign, int pos, int y, int l, int r, int rt, int val) {
 52     if(l == r) {
 53         if(!sign) {
 54             maxx[pos][rt] = minn[pos][rt] = val;
 55         } else {
 56             maxx[pos][rt] = max(maxx[pos<<1][rt], maxx[pos<<1|1][rt]);
 57             minn[pos][rt] = min(minn[pos<<1][rt], minn[pos<<1|1][rt]);
 58         }
 59         return ;
 60     }
 61     int m = l+r>>1;
 62     if(y<=m)
 63         sub_update(sign, pos, y, lson, val);
 64     else
 65         sub_update(sign, pos, y, rson, val);
 66     pushUp(pos, rt);
 67 }
 68 void update(int x, int y, int l, int r, int rt, int val) {
 69     if(l == r) {
 70         sub_update(0, rt, y, 1, n, 1, val);
 71         return ;
 72     }
 73     int m = l+r>>1;
 74     if(x<=m)
 75         update(x, y, lson, val);
 76     else
 77         update(x, y, rson, val);
 78     sub_update(1, rt, y, 1, n, 1, val);
 79 }
 80 void sub_query(int pos, int L, int R, int l, int r, int rt) {
 81     if(L<=l&&R>=r) {
 82         max_ans = max(max_ans, maxx[pos][rt]);
 83         min_ans = min(min_ans, minn[pos][rt]);
 84         return ;
 85     }
 86     int m = l+r>>1;
 87     if(L<=m)
 88         sub_query(pos, L, R, lson);
 89     if(R>m)
 90         sub_query(pos, L, R, rson);
 91 }
 92 void query(int LX, int RX, int LY, int RY, int l, int r, int rt) {
 93     if(LX<=l&&RX>=r) {
 94         sub_query(rt, LY, RY, 1, n, 1);
 95         return ;
 96     }
 97     int m = l+r>>1;
 98     if(LX<=m)
 99         query(LX, RX, LY, RY, lson);
100     if(RX>m)
101         query(LX, RX, LY, RY, rson);
102 }
103 int main()
104 {
105     int t, x, y, l, q, cnt = 1;
106     cin>>t;
107     while (t--) {
108         scanf("%d", &n);
109         build(1, n, 1);
110         cin>>q;
111         printf("Case #%d:\n", cnt++);
112         while(q--) {
113             scanf("%d%d%d", &x, &y, &l);
114             min_ans = inf, max_ans = 0;
115             int LX = max(x-l/2, 1);
116             int RX = min(x+l/2, n);
117             int LY = max(y-l/2, 1);
118             int RY = min(y+l/2, n);
119             query(LX , RX, LY, RY, 1, n, 1);
120             int ans = (min_ans+max_ans)/2;
121             printf("%d\n", ans);
122             update(x, y, 1, n, 1, ans);
123         }
124     }
125 }

 

UVALive 6709 - Mosaic 二维线段树

标签:

原文地址:http://www.cnblogs.com/yohaha/p/5025573.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!