题解:
二维RMQ中的ST算法的模板题
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> #include<map> #include<set> #include<vector> using namespace std; using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long #define MS(x,y) memset(x,y,sizeof(x)) #define MC(x,y) memcpy(x,y,sizeof(x)) #define ls o<<1 #define rs o<<1|1 #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) typedef pair<int,int> P; const double eps=1e-9; const int maxn=50100; const int N=1e9; const int mod=1e9+7; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } //----------------------------------------------------------------------------- int m[255][255]; int mi[255][255][8][8],mx[255][255][8][8]; int n,b,k,x,y; void rmq_init() { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) mi[i][j][0][0]=mx[i][j][0][0]=m[i][j]; int Mx=(int)(log(n*1.0)/log(2.0)); int My=(int)(log(n*1.0)/log(2.0)); for(int i=0;i<=Mx;i++) for(int j=0;j<=My;j++) { if(i==0&&j==0) continue; for(int Row=1;Row+(1<<i)-1<=n;Row++) for(int Col=1;Col+(1<<j)-1<=n;Col++) { if(i)//因为已经算了只有一列时,每一一行的极值,那么有多列时,就不需要算行了 { mx[Row][Col][i][j]=max(mx[Row][Col][i-1][j],mx[Row+(1<<(i-1))][Col][i-1][j]); mi[Row][Col][i][j]=min(mi[Row][Col][i-1][j],mi[Row+(1<<(i-1))][Col][i-1][j]); } else//当矩形只有一列时,那么算一行的极值 { mx[Row][Col][i][j]=max(mx[Row][Col][i][j-1],mx[Row][Col+(1<<(j-1))][i][j-1]); mi[Row][Col][i][j]=min(mi[Row][Col][i][j-1],mi[Row][Col+(1<<(j-1))][i][j-1]); } } } } int rmq_max(int x1,int y1,int x2,int y2) { int kx=(int)(log(x2-x1+1.0)/log(2.0)); int ky=(int)(log(y2-y1+1.0)/log(2.0)); x2=x2-(1<<kx)+1; y2=y2-(1<<ky)+1; return max(max(mx[x1][y1][kx][ky],mx[x1][y2][kx][ky]),max(mx[x2][y1][kx][ky],mx[x2][y2][kx][ky]));//算4部分,左右上下 } int rmq_min(int x1,int y1,int x2,int y2) { int kx=(int)(log(x2-x1+1.0)/log(2.0)); int ky=(int)(log(y2-y1+1.0)/log(2.0)); x2=x2-(1<<kx)+1; y2=y2-(1<<ky)+1; return min(min(mi[x1][y1][kx][ky],mi[x1][y2][kx][ky]),min(mi[x2][y1][kx][ky],mi[x2][y2][kx][ky])); } int main(){ scanf("%d%d%d",&n,&b,&k); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&m[i][j]); rmq_init(); while(k--){ scanf("%d%d",&x,&y); printf("%d\n",rmq_max(x,y,x+b-1,y+b-1)-rmq_min(x,y,x+b-1,y+b-1)); } return 0; }
时间: 2024-10-09 03:20:45