Educational Codeforces Round 28 D. Monitor 二维rmq

参考:http://blog.csdn.net/just_sort/article/details/78322659

D. Monitor

题意:一份n*m的显示屏上某些像素点(xi,yi)在t[i]时间会坏掉,如果坏的像素点连成k*k大小,这个显示屏就不能用了,问显示屏损坏的最小的时间,如果不会损坏,输出-1

解法:直接2分时间,那么这个问题就变成了能否找到k*k的矩阵,直接二维前缀和O(n^2)即可。

题解说用二分+前缀和。
这二维rmq也可以

#include
using namespace std;
#define maxn 510
#define INF 0x3f3f3f3f
int dp[maxn][maxn][10][10];
int mm[maxn];
int val[maxn][maxn];
void initRMQ(int n,int m)
{
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            dp[i][j][0][0]=val[i][j];
    for(int ii=0;ii<=mm[n];++ii)
        for(int jj=0;jj<=mm[m];++jj)
            if(ii+jj)
                for(int i=1;i+(1<1<=n;++i)
                    for(int j=1;j+(1<1<=m;++j)
                    {
                        if(ii) dp[i][j][ii][jj]=max(dp[i][j][ii-1][jj],dp[i+(1<<(ii-1))][j][ii-1][jj]);
                        else  dp[i][j][ii][jj]=max(dp[i][j][ii][jj-1],dp[i][j+(1<<(jj-1))][ii][jj-1]);
                    }
}
int rmq(int x1,int y1,int x2,int y2)
{
    int k1=mm[x2-x1+1];
    int k2=mm[y2-y1+1];
    x2=x2-(1<1;
    y2=y2-(1<1;
    return max(max(dp[x1][y1][k1][k2],dp[x1][y2][k1][k2]),max(dp[x2][y1][k1][k2],dp[x2][y2][k1][k2]));
}
int main()
{
    mm[0]=-1;
    for(int i=1;i1))==0)?mm[i-1]+1:mm[i-1];
    int n,m,k,q;
    scanf("%d%d%d%d",&n,&m,&k,&q);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j) 
            val[i][j]=INF;
    while(q--)
    {
        int x,y,t;
        scanf("%d%d%d",&x,&y,&t);
        val[x][y]=t;
    }
    initRMQ(n,m);
    int ans=INF;
    for(int i=1;i+k-1<=n;++i)
        for(int j=1;j+k-1<=m;++j)
        {
            int tmp=rmq(i,j,i+k-1,j+k-1);
            if(ans==-1||tmpif(ans>=INF) ans=-1;
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(数据结构-树状数组)