昨天刷水累死蒟蒻了。。。

每天一到题解总还是要写的。。。于是就是这个了!

二维RMQ,第一反应是二维线段树,妥妥MLE + TLE

想起来去年市选小题有一道一模一样的,我当时就是写二维线段树,然后MLE0分、、、真是悲剧

 

发现长度是固定的为n,和动态规划的某个叫单调队列的优化很像:

先求出每一列的某个点向下n个数的最大/小值,然后求出每一行某个点向右的n个单调队列的最大/小值,方法依旧是单调队列。。。

程序写的很烦。。。是照抄网上的。。。(太烦了不想写呢><)

 

 1 /**************************************************************
 2     Problem: 1047
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:1604 ms
 7     Memory:16600 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <algorithm>
12  
13 using namespace std;
14 const int N = 1005;
15  
16 int mp[N][N];
17 int q[N][N], h[N], t[N], Q[N];
18 int mx[N][N], mn[N][N];
19 int s, e, a, b, n;
20  
21 inline int read(){
22     int x = 0, sgn = 1;
23     char ch = getchar();
24     while (ch < '0' || ch > '9'){
25         if (ch == '-') sgn = -1;
26         ch = getchar();
27     }
28     while (ch >= '0' && ch <= '9'){
29         x = x * 10 + ch - '0';
30         ch = getchar();
31     }
32     return sgn * x;
33 }
34  
35 void getmax(){
36     for (int i = 1; i <= b; ++i)
37         h[i] = 1, t[i] = 0;
38     for (int i = 1; i <= a; ++i){
39         for (int j = 1; j <= b; ++j){
40             while (h[j] <= t[j] && i - q[j][h[j]] >= n) ++h[j];
41             while (h[j] <= t[j] && mp[q[j][t[j]]][j] <= mp[i][j]) --t[j];
42             q[j][++t[j]] = i;
43         }
44         e = 0, s = 1;
45         for (int j = 1; j <= b; ++j){
46             while (s <= e && j - Q[s] >= n) ++s;
47             while (s <= e && mp[q[Q[e]][h[Q[e]]]][Q[e]] <= mp[q[j][h[j]]][j]) --e;
48             Q[++e] = j;
49             mx[i][j] = mp[q[Q[s]][h[Q[s]]]][Q[s]];
50         }
51     }
52 }
53  
54 void getmin(){
55     for (int i = 1; i <= b; ++i)
56         h[i] = 1, t[i] = 0;
57     for (int i = 1; i <= a; ++i){
58         for (int j = 1; j <= b; ++j){
59             while (h[j] <= t[j] && i - q[j][h[j]] >= n) ++h[j];
60             while (h[j] <= t[j] && mp[q[j][t[j]]][j] >= mp[i][j]) --t[j];
61             q[j][++t[j]] = i;
62         }
63         e = 0, s = 1;
64         for (int j = 1; j <= b; ++j){
65             while (s <= e && j - Q[s] >= n) ++s;
66             while (s <= e && mp[q[Q[e]][h[Q[e]]]][Q[e]] >= mp[q[j][h[j]]][j]) --e;
67             Q[++e] = j;
68             mn[i][j] = mp[q[Q[s]][h[Q[s]]]][Q[s]];
69         }
70     }
71 }
72  
73 int main(){
74     a = read(), b = read(), n = read();
75     for (int i = 1; i <= a; ++i)
76         for (int j = 1; j <= b; ++j)
77             mp[i][j] = read();
78      
79     getmax();
80     getmin();
81     int ans = (int) 1e9;
82     for (int i = n; i <= a; ++i)
83         for (int j = n; j <= b; ++j)
84             ans = min(ans, mx[i][j] - mn[i][j]);
85     printf("%d\n", ans);
86     return 0;
87 }
View Code

 

posted on 2014-10-20 21:55  Xs酱~  阅读(352)  评论(0编辑  收藏  举报