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 }
解法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 }