首页 > 代码库 > POJ2019 Cornfields

POJ2019 Cornfields

题解:

二维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;}

 

POJ2019 Cornfields