POJ--2019(模拟 / 二维线段树)

2015-01-25 00:59:14

思路:解法1:可以暴力预处理出每个点的答案...(当然维护一个正方形框可以优化这个过程)...

     解法2:建立二维线段树,然后查询...

   解法3.... ?

解法1:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=1;i<=(n);++i)
17 #define REV(i,n) for(int i=(n);i>=1;--i)
18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
20 #define MP(a,b) make_pair(a,b)
21 
22 typedef long long ll;
23 typedef pair<int,int> pii;
24 const int INF = (1 << 30) - 1;
25 const int maxn = 300;
26 
27 int N,B,K;
28 int g[maxn][maxn];
29 int cnt[maxn],tmp[maxn],ans[maxn][maxn];
30 
31 int Solve(){
32     int tmax = -1,tmin = -1;
33     FOR(i,0,250) if(cnt[i]){
34         tmin = i;
35         break;
36     }
37     RFOR(i,250,0) if(cnt[i]){
38         tmax = i;
39         break;
40     }
41     return tmax - tmin;
42 }
43 
44 int main(){
45     while(scanf("%d%d%d",&N,&B,&K) != EOF){
46         REP(i,N) REP(j,N){
47             scanf("%d",&g[i][j]);
48         }
49         MEM(cnt,0);
50         REP(i,B) REP(j,B)
51             cnt[g[i][j]]++;
52         REP(i,N - B + 1){
53             if(i > 1){
54                 REP(k,B) cnt[g[i - 1][k]]--;
55                 REP(k,B) cnt[g[i + B - 1][k]]++;
56             }
57             memcpy(tmp,cnt,sizeof(tmp));
58             ans[i][1] = Solve();
59             FOR(j,2,N - B + 1){
60                 REP(k,B) cnt[g[i + k - 1][j - 1]]--;
61                 REP(k,B) cnt[g[i + k - 1][j + B - 1]]++;
62                 ans[i][j] = Solve();
63             }
64             memcpy(cnt,tmp,sizeof(tmp));
65         }
66         int a,b;
67         REP(i,K){
68             scanf("%d%d",&a,&b);
69             printf("%d\n",ans[a][b]);
70         }
71     }
72     return 0;
73 }
View Code

解法2:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <vector>
  6 #include <map>
  7 #include <set>
  8 #include <stack>
  9 #include <queue>
 10 #include <string>
 11 #include <iostream>
 12 #include <algorithm>
 13 using namespace std;
 14 
 15 #define getmid(l,r) ((l)+((r)-(l))/2)
 16 #define MEM(a,b) memset(a,b,sizeof(a))
 17 #define REP(i,n) for(int i=1;i<=(n);++i)
 18 #define REV(i,n) for(int i=(n);i>=1;--i)
 19 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
 20 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
 21 #define MP(a,b) make_pair(a,b)
 22 
 23 typedef long long ll;
 24 typedef pair<int,int> pii;
 25 const int INF = (1 << 30) - 1;
 26 const int maxn = 255;
 27 
 28 int N,B,K;
 29 int g[maxn][maxn];
 30 int X1,Y1,X2,Y2;
 31 
 32 struct SMT_2{
 33     int tmax[maxn << 2][maxn << 2];
 34     int tmin[maxn << 2][maxn << 2];
 35     void clear(){
 36         MEM(tmax,0);
 37         MEM(tmin,0);
 38     }
 39     void Build_tree_y(int xval,int xp,int yp,int l,int r){
 40         if(l == r){
 41             tmax[xp][yp] = tmin[xp][yp] = g[xval][l];
 42             return;
 43         }
 44         int mid = getmid(l,r);
 45         Build_tree_y(xval,xp,yp << 1,l,mid);
 46         Build_tree_y(xval,xp,yp << 1|1,mid + 1,r);
 47         tmax[xp][yp] = max(tmax[xp][yp << 1],tmax[xp][yp << 1|1]);
 48         tmin[xp][yp] = min(tmin[xp][yp << 1],tmin[xp][yp << 1|1]);
 49     }
 50     void Build_tree_y2(int xp,int yp,int l,int r){
 51         tmax[xp][yp] = max(tmax[xp << 1][yp],tmax[xp << 1|1][yp]);
 52         tmin[xp][yp] = min(tmin[xp << 1][yp],tmin[xp << 1|1][yp]);
 53         if(l == r) return;
 54         int mid = getmid(l,r);
 55         Build_tree_y2(xp,yp << 1,l,mid);
 56         Build_tree_y2(xp,yp << 1|1,mid + 1,r);
 57     }
 58     void Build_tree_x(int p,int l,int r){
 59         if(l == r){
 60             Build_tree_y(l,p,1,1,N);
 61             return;
 62         }
 63         int mid = getmid(l,r);
 64         Build_tree_x(p << 1,l,mid);
 65         Build_tree_x(p << 1|1,mid + 1,r);
 66         Build_tree_y2(p,1,1,N);
 67     }
 68     pii Query_tree_y(int xp,int yp,int l,int r){
 69         if(Y1 <= l && r <= Y2){
 70             return MP(tmax[xp][yp],tmin[xp][yp]);
 71         }
 72         int mid = getmid(l,r);
 73         pii res(-1,-1),tmp(-1,-1);
 74         if(Y1 <= mid) res = Query_tree_y(xp,yp << 1,l,mid);
 75         if(Y2 > mid) tmp = Query_tree_y(xp,yp << 1|1,mid + 1,r);
 76         if(res.first == -1) res =tmp;
 77         else if(tmp.first != -1){
 78             res.first = max(res.first,tmp.first);
 79             res.second = min(res.second,tmp.second);
 80         }
 81         return res;
 82     }
 83     pii Query_tree_x(int p,int l,int r){
 84         if(X1 <= l && r <= X2){
 85             return Query_tree_y(p,1,1,N);
 86         }
 87         int mid = getmid(l,r);
 88         pii res(-1,-1),tmp(-1,-1);
 89         if(X1 <= mid) res = Query_tree_x(p << 1,l,mid);
 90         if(X2 > mid) tmp = Query_tree_x(p << 1|1,mid + 1,r);
 91         if(res.first == -1) res = tmp;
 92         else if(tmp.first != -1){
 93             res.first = max(res.first,tmp.first);
 94             res.second = min(res.second,tmp.second);
 95         }
 96         return res;
 97     }
 98 }smt;
 99 
100 int main(){
101     int a,b;
102     while(scanf("%d%d%d",&N,&B,&K) != EOF){
103         smt.clear();
104         REP(i,N) REP(j,N) scanf("%d",&g[i][j]);
105         smt.Build_tree_x(1,1,N);
106         REP(i,K){
107             scanf("%d%d",&a,&b);
108             X1 = a,X2 = a + B - 1;
109             Y1 = b,Y2 = b + B - 1;
110             pii ans = smt.Query_tree_x(1,1,N);
111             printf("%d\n",ans.first - ans.second);
112         }
113     }
114     return 0;
115 }

 

posted @ 2015-01-25 01:03  Naturain  阅读(134)  评论(0编辑  收藏  举报