hdu 2888 Check Corners 二维RMQ

可以说是刚好这个空间大小,卡的刚好。

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <math.h>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int N = 302;
 8 int n, m;
 9 int val[N][N];
10 int dpmax[N][N][9][9];
11 //int dpmax[a][b][c][d];
12 //从val[a][b]-val[a+2^c-1][b+2^d-1];的最大值
13 
14 void ST()
15 {
16     int i, j, r, c, k1, k2;
17     for (i = 1; i <= n; i++)
18     for (j = 1; j <= m; j++)
19         dpmax[i][j][0][0] = val[i][j];
20     k1 = (int)(log(double(n)) / log(2.0));
21     k2 = (int)(log(double(m)) / log(2.0));
22     //k1 = log2(n);
23     //k2 = log2(m);
24     for (i = 0; i <= k1; i++)
25     {
26         for (j = 0; j <= k2; j++)
27         {
28             if (i == 0 && j == 0)  continue;
29             for (r = 1; r + (1 << i) - 1 <= n; r++)
30             {
31                 for (c = 1; c + (1 << j) - 1 <= m; c++)
32                 {
33                     if (i == 0)
34                         dpmax[r][c][i][j] = max(dpmax[r][c][i][j - 1], dpmax[r][c + (1 << (j - 1))][i][j - 1]);
35                     else
36                         dpmax[r][c][i][j] = max(dpmax[r][c][i - 1][j], dpmax[r + (1 << (i - 1))][c][i - 1][j]);
37                 }
38             }
39         }
40     }
41 }
42 
43 int query(int r1, int c1, int r2, int c2)
44 {
45     int kr = (int)(log(double(r2 - r1 + 1)) / log(2.0));
46     int kc = (int)(log(double(c2 - c1 + 1)) / log(2.0));
47     //k = log2(y-x+1);
48     int t1 = dpmax[r1][c1][kr][kc];
49     int t2 = dpmax[r2 - (1 << kr) + 1][c1][kr][kc];
50     int t3 = dpmax[r1][c2 - (1 << kc) + 1][kr][kc];
51     int t4 = dpmax[r2 - (1 << kr) + 1][c2 - (1 << kc) + 1][kr][kc];
52 
53     return max(max(t1, t2), max(t3, t4));
54 }
55 
56 int main()
57 {
58     int i, j, k;
59     int r1, c1, r2, c2;
60     while (~scanf("%d%d", &n, &m))
61     {
62         for (i = 1; i <= n; i++)
63         for (j = 1; j <= m; j++)
64             scanf("%d", &val[i][j]);
65         ST();//初始化
66         scanf("%d", &k);
67         while (k--)
68         {
69             scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
70             int ret = query(r1, c1, r2, c2);
71             printf("%d ", ret);
72             if (val[r1][c1] == ret || val[r1][c2] == ret || val[r2][c1] == ret || val[r2][c2] == ret)
73                 printf("yes\n");
74             else 
75                 printf("no\n");
76         }
77     }
78     return 0;
79 }

 

转载于:https://www.cnblogs.com/ouyang_wsgwz/p/7846573.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值