您的位置:首页 > 产品设计 > UI/UE

RMQ (Range Minimum/Maximum Query)问题

2015-03-13 10:08 417 查看
**************************************************************************************************************

一维RMQ查找最大值下标模板

一维RMQ模版

二维RMQ模板

**************************************************************************************************************

①一维RMQ查找最大值下标模板

int n,q;

int val
;

int mx[20]
;

int tlog
;

int p[21];

void make_maxrmq() {

int i,j,k;

for(i=1;i<=n;i++) mx[0][i]=i;

for(j=1;p[j]<=n;j++)

for(i=1;i+p[j]-1<=n;i++) {

if(val[ mx[j-1][i] ]>val[ mx[j-1][i+p[j-1]] ])

mx[j][i]=mx[j-1][i];

else

mx[j][i]=mx[j-1][i+p[j-1]];

}

}

int maxrmq(int a,int b) {

int k=tlog[b-a+1];

int ret;

if(val[ mx[k][a] ]>val[ mx[k][b-p[k]+1] ]) ret=mx[k][a];

else ret=mx[k][b-p[k]+1];

return ret;

}

void init_rmq() {

for(int i=0;i<=20;i++) p[i]=(1<<i);

tlog[0]=-1;

for(int i=1;i<=50000;i++)

tlog[i]=(i&(i-1))?tlog[i-1]:tlog[i-1]+1;

}

**************************************************************************************************************

②一维RMQ模版

int n,q;

int a
;

int mx[20]
,mi[20]
;

int tlog
;

int p[21];

void make_maxrmq() {

int i,j,k;

for(i=1;i<=n;i++) mx[0][i]=a[i];

for(j=1;p[j]<=n;j++)

for(i=1;i+p[j]-1<=n;i++)

mx[j][i]=max(mx[j-1][i],mx[j-1][i+p[j-1]]);

}

void make_minrmq() {

int i,j,k;

for(i=1;i<=n;i++) mi[0][i]=a[i];

for(j=1;p[j]<=n;j++)

for(i=1;i+p[j]-1<=n;i++)

mi[j][i]=min(mi[j-1][i],mi[j-1][i+p[j-1]]);

}

int maxrmq(int a,int b) {

int k=tlog[b-a+1];

return max(mx[k][a],mx[k][b-p[k]+1]);

}

int minrmq(int a,int b) {

int k=tlog[b-a+1];

return min(mi[k][a],mi[k][b-p[k]+1]);

}

void init() {

for(int i=0;i<=20;i++) p[i]=(1<<i);

tlog[0]=-1;

for(int i=1;i<=50000;i++)

tlog[i]=(i&(i-1))?tlog[i-1]:tlog[i-1]+1;

}

int main()

{

init();

int s,t;

while(scanf("%d%d",&n,&q)!=EOF) {

for(int i=1;i<=n;i++) scanf("%d",&a[i]);

make_maxrmq();

make_minrmq();

while(q--) {

scanf("%d%d",&s,&t);

printf("%d\n",maxrmq(s,t)-minrmq(s,t));

}

}

}

**************************************************************************************************************

③二维RMQ模板

==========================================================================================

①【普通版】

int n,m,q;

int a

;

int mx[10][10]

;

int tlog
;

int p[11];

void make_maxrmq() {

int i,j,k,l;

for(i=0;i<=n;i++)

for(j=0;j<=m;j++)

mx[0][0][i][j]=a[i][j];

for(i=0;p[i]<=n;i++) {

int di=p[i];

for(j=0;p[j]<=m;j++) {

if(i==0&&j==0) continue;

int dj=p[j];

for(k=1;k+di-1<=n;k++) {

for(l=1;l+dj-1<=m;l++) {

if(i==0)

mx[i][j][k][l]=max(mx[i][j-1][k][l],mx[i][j-1][k][l+p[j-1]]);

else

mx[i][j][k][l]=max(mx[i-1][j][k][l],mx[i-1][j][k+p[i-1]][l]);

}

}

}

}

}

int maxrmq(int x1,int x2,int y1,int y2) {

int kn=tlog[x2-x1+1]; //(int)(log(x2-x1+1.0)/log(2.0));

int km=tlog[y2-y1+1]; //(int)(log(y2-y1+1.0)/log(2.0));

int v1=mx[kn][km][x1][y1];

int v2=mx[kn][km][x1][y2-p[km]+1];

int v3=mx[kn][km][x2-p[kn]+1][y1];

int v4=mx[kn][km][x2-p[kn]+1][y2-p[km]+1];

return max(max(v1,v2),max(v3,v4));

}

void init_rmq() {

for(int i=0;i<=10;i++) p[i]=1<<i;

tlog[0]=-1;

for(int i=1;i<=300;i++)

tlog[i]=(i&(i-1))?tlog[i-1]:tlog[i-1]+1;

}

int main()

{

init_rmq();

int i,j;

int x1,x2,y1,y2;

while(scanf("%d%d",&n,&m)!=EOF) {

for(i=1;i<=n;i++)

for(j=1;j<=m;j++) scan_d(a[i][j]);

make_maxrmq();

scanf("%d",&q);

while(q--) {

scan_d(x1); scan_d(y1);

scan_d(x2); scan_d(y2);

int ans=maxrmq(x1,x2,y1,y2);

printf("%d ",ans);

if(ans==a[x1][y1]||ans==a[x1][y2]||ans==a[x2][y1]||ans==a[x2][y2])

puts("yes");

else

puts("no");

}

}

return 0;

}

==========================================================================================

②【终极版】

//数组优化:四维降三维

//二维RMQ,区间求最值

// + tlog[] 优化

int n,m,q;

int val

;

int mx[10]

;

int tlog
;

int pw[11];

void make_maxrmq() {

int i,j,k;

int nn=max(n,m);

for(k=0;pw[k]<=nn;k++)

for(i=1;i<=n;i++)

for(j=1;j<=m;j++) mx[k][i][j]=val[i][j];

for(k=1;pw[k]<=nn;k++) {

for(i=1;i<=n;i++) {

for(j=1;j<=m;j++) {

mx[k][i][j]=mx[k-1][i][j];

if(i+pw[k-1]<=n)

mx[k][i][j]=max(mx[k][i][j],mx[k-1][i+pw[k-1]][j]);

if(j+pw[k-1]<=m)

mx[k][i][j]=max(mx[k][i][j],mx[k-1][i][j+pw[k-1]]);

if(i+pw[k-1]<=n&&j+pw[k-1]<=m)

mx[k][i][j]=max(mx[k][i][j],mx[k-1][i+pw[k-1]][j+pw[k-1]]);

}

}

}

}

int maxrmq(int x1,int y1,int x2,int y2) {

int i=tlog[x2-x1+1]; //(int)(log(x2-x1+1.0)/log(2.0));

int j=tlog[y2-y1+1]; //(int)(log(y2-y1+1.0)/log(2.0));

int k=min(i,j);

if(i>j) i=j;

int ret=mx[0][x1][y1];

for(i=x1;i<=x2;i+=pw[k]) {

if(i+pw[k]>x2) i=x2-pw[k]+1;

for(j=y1;j<=y2;j+=pw[k]) {

if(j+pw[k]>y2) j=y2-pw[k]+1;

ret=max(ret,mx[k][i][j]);

}

}

return ret;

}

void init_rmq() {

for(int i=0;i<=10;i++) pw[i]=1<<i;

tlog[0]=-1;

for(int i=1;i<=300;i++)

tlog[i]=(i&(i-1))?tlog[i-1]:tlog[i-1]+1;

}

int main()

{

init_rmq();

int i,j;

int x1,x2,y1,y2;

while(scanf("%d%d",&n,&m)!=EOF) {

for(i=1;i<=n;++i)

for(j=1;j<=m;++j) scan_d(val[i][j]);

make_maxrmq();

scanf("%d",&q);

while(q--) {

scan_d(x1); scan_d(y1);

scan_d(x2); scan_d(y2);

int ret=maxrmq(x1,y1,x2,y2);

printf("%d ",ret);

if(ret==val[x1][y1]||ret==val[x1][y2]||ret==val[x2][y1]||ret==val[x2][y2])

puts("yes");

else

puts("no");

}

}

return 0;

}

**************************************************************************************************************

**************************************************************************************************************
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: