hdu2888(二维RMQ)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2888

之前可能学了假的二维RMQ,跑了9000多ms。。。。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=320;
 7 int p[maxn][maxn];
 8 int pmax[maxn][maxn][20];
 9 int  n,m,k;
10 
11 void RMQ_INIT()
12 {
13     int f=log(n+0.0)/log(2.0);
14     for(int i=1;i<=n;i++)
15         for(int j=1;j<=m;j++)
16             pmax[i][j][0]=p[i][j];
17     for(int i=1;i<=n;i++)
18     for(int k=1;k<=f;k++)
19     for(int j=1;j+(1<<k)-1<=m;j++)
20     {
21         pmax[i][j][k]=max(pmax[i][j][k-1],pmax[i][j+(1<<k-1)][k-1]);
22     }
23     return;
24 }
25 
26 
27 int rmq(int r1,int c1,int r2,int c2 )
28 {
29     int l=c1,r=c2;
30     int k=log(r+0.0-l+1)/log(2.0);
31     int maxx=-0x3f3f3f3f;
32     for(int i=r1;i<=r2;i++)
33     {
34         maxx=max(maxx,max(pmax[i][l][k],pmax[i][r-(1<<k)+1][k]));
35     }
36     return maxx;
37 }
38 int main()
39 {
40     while(scanf("%d%d",&n,&m)!=EOF)
41     {
42         for(int i=1;i<=n;i++)
43             for(int j=1;j<=m;j++)
44                 scanf("%d",&p[i][j]);
45         RMQ_INIT();
46         int r1,r2,c1,c2;
47         scanf("%d",&k);
48         while(k--)
49         {
50             scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
51             int x=rmq(r1,c1,r2,c2);
52             printf("%d ",x);
53             if(p[r1][c1]==x||p[r1][c2]==x||p[r2][c2]==x||p[r2][c1]==x)
54                 puts("yes");
55             else puts("no");
56         }
57     }
58 
59 }
View Code

 

二维RMQ

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=320;
 7 int p[maxn][maxn];
 8 int pmax[maxn][maxn][9][9]; //不要盲目开大
 9 int  n,m,k;
10 
11 void RMQ_INIT()
12 {
13     for(int i=1;i<=n;i++)
14         for(int j=1;j<=m;j++)
15             pmax[i][j][0][0]=p[i][j];
16     for(int ii=0;(1<<ii)<=n;ii++)
17     for(int jj=0;(1<<jj)<=m;jj++)
18     if(ii+jj)
19         for(int i=1;i+(1<<ii)-1<=n;i++)
20         for(int j=1;j+(1<<jj)-1<=m;j++)
21         if(ii) pmax[i][j][ii][jj]=max(pmax[i][j][ii-1][jj],pmax[i+(1<<ii-1)][j][ii-1][jj]);
22         else pmax[i][j][ii][jj]=max(pmax[i][j][ii][jj-1],pmax[i][j+(1<<jj-1)][ii][jj-1]);
23    return ;
24 }
25 
26 
27 int rmq(int r1,int c1,int r2,int c2 )
28 {
29    int k1=0,k2=0;
30    while((1<<k1+1)<=r2-r1+1) k1++;
31    while((1<<k2+1)<=c2-c1+1) k2++;
32     r2=r2-(1<<k1)+1;
33     c2=c2-(1<<k2)+1;
34     return max(max(pmax[r1][c1][k1][k2],pmax[r1][c2][k1][k2]),max(pmax[r2][c1][k1][k2],pmax[r2][c2][k1][k2]));
35 }
36 int main()
37 {
38     while(scanf("%d%d",&n,&m)!=EOF)
39     {
40         for(int i=1;i<=n;i++)
41             for(int j=1;j<=m;j++)
42                 scanf("%d",&p[i][j]);
43         RMQ_INIT();
44         int r1,r2,c1,c2;
45         scanf("%d",&k);
46         while(k--)
47         {
48             scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
49             int x=rmq(r1,c1,r2,c2);
50             printf("%d ",x);
51             if(p[r1][c1]==x||p[r1][c2]==x||p[r2][c2]==x||p[r2][c1]==x) puts("yes");
52             else puts("no");
53         }
54     }
55 }

 

posted @ 2017-04-24 17:24  yijiull  阅读(197)  评论(0编辑  收藏  举报