Codeforces Round # 619 (Div. 2) E +-dimensional thinking RMQ

Title: https: //codeforces.com/contest/1301/problem/E

Meaning of the questions: give n * m graphics, q an inquiry, Always ask ask ask largest range of legal logo What is the size

Analysis: Because the logo is a small square four same color component, we consider an array val [i] [j] represents a [i] [j] position of 'R', [i + 1] [j] position is 'Y', [i] [j + 1] to the position 'G', [i + 1] [j + 1] to the position 'B' the maximum side length of a pattern that can be formed is much;

   Since the maximum square so long as the maximum pre-squares 'R' can form a square along the upper left, the maximum square "Y" that can be formed along the lower left, 'G' that can be formed along the upper right, "B" along the lower right the maximum square that can be formed, and then the position [i] [j] will take these four min;

   For inquiries, we only half the answer found to the maximum qualifying on the line, pay attention to half of the mid here, assuming ask [r1, c1, r2, c2], the search access should [r1 + mid-1, c1 + mid -1, r2-mid, the c2-mid] the scope of the search is legitimate;

   Because we are required to meet the conditions of the line in two mid time sharing, so here for multiplying process val;

   Legitimacy: legitimate because of the small pattern in a certain pattern inside a large legal, so take val pattern may be more than the scope of inquiry, but we have to ask the above range as reduced, so it is legal

#include<bits/stdc++.h>
using namespace std;
const int M=505;
const int N=10;
int ex[4][M][M];
int n,m,q;
int val[M][M],f[N][N][M][M],lg[M];
char s[M][M];
void RMQ(int n,int m){
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            f[0][0][i+1][j+1]=val[i][j];
    for(int i=2;i<M;i++)
        lg[i]=1+lg[i/2];
    for(int i=1;i<=n;i++)
        for(int k2=1;(1<<k2)<=m;k2++)
            for(int j=1;j<=m-(1<<k2)+1;j++)
                f[0][k2][i][j]=max(f[0][k2-1][i][j],f[0][k2-1][i][j+(1<<(k2-1))]);
    for(int k1=1;(1<<k1)<=n;k1++)
        for(int i=1;i<=n-(1<<k1)+1;i++)
            for(int k2=0;(1<<k2)<=m;k2++)
                for(int j=1;j<=m-(1<<k2)+1;j++)
                    f[k1][k2][i][j]=max(f[k1-1][k2][i][j],f[k1-1][k2][i+(1<<(k1-1))][j]);
}


int query(int x1,int y1,int x2,int y2){
    int k1=lg[x2-x1+1];
    int k2=lg[y2-y1+1];
    x2=x2-(1<<k1)+1;
    y2=y2-(1<<k2)+1;
    return max(f[k1][k2][x1][y1],max(f[k1][k2][x1][y2],max(f[k1][k2][x2][y1],f[k1][k2][x2][y2])));
}
bool check(int r1,int c1,int r2,int c2,int midd){
    r1 = r1 + mite 1 ;
    c1 = c1 + mite 1 ;
    r2 = 2- mites;
    c2=c2-midd;
    if(r1>r2||c1>c2)
        return false;
    return query(r1,c1,r2,c2)>=midd;
}
void Color ( int FX, int FY, char C, int K) { /// depending incoming parameters, the composition of the same color in different directions the maximum square 
    int STX = 0 , STY = 0 ;
     IF (FX == - . 1 ) = N- STX . 1 ;
     IF (FY == - . 1 ) STY = M- . 1 ;
     /// the while traversing a two-dimensional array of 
    the while (STX <&& n-STX> = 0 ) {
         the while (STY <&& STY m> = 0 ) {
             IF ( S [STX] [STY] == C) {
                ex[k][stx][sty]=1;
                if(stx-fx>=0&&stx-fx<n&&sty-fy>=0&&sty-fy<m){///正方形区域取最小值 
                    if(s[stx-fx][sty]==c&&s[stx][sty-fy]==c&&s[stx-fx][sty-fy]==c){
                        ex [k] [STX] [Jan.] = min (Ex [k] [stx- fx] [Jan.]
                                         min (ex [k] [STX] [Jan. -fy] ex [k] [stx-fx] [Jan-fy])) + 1 ;
                    }
                }
            }
            January + = fy;
        }
        sty=0;if(fy==-1)sty=m-1;
        STX + = example;
    }
}
int main () {
    scanf("%d%d%d",&n,&m,&q);
    for(int i=0;i<n;i++)
        scanf("%s",s[i]); 
    //1
    color(1,1,'R',0);
    Color ( - 1 , 1 , ' Y ' , 1 );
    color(1,-1,'G',2);
    color(-1,-1,'B',3);
    for(int i=0;i<n-1;i++){
        for(int j=0;j<m-1;j++){
            if(s[i][j]=='R'&&s[i+1][j]=='Y'&&s[i][j+1]=='G'&&s[i+1][j+1]=='B'){
                val[i][j]=min(ex[0][i][j],min(ex[1][i+1][j],min(ex[2][i][j+1],ex[3][i+1][j+1])));
            }
        }
    }
    //2
    RMQ(n,m);

    //3
    for(int i=0;i<q;i++){
        int r1,c1,r2,c2,ans=0;
        scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
        int l=0,r=min(r2-r1,c2-c1);
        while(l<=r){
            int midd=(l+r)>>1;
            if(check(r1,c1,r2,c2,midd)){
                ans = tired;
                l = mite + 1 ;
            }
            else 
                r = mite 1 ;
        }
        printf("%d\n",4*ans*ans);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/starve/p/12348177.html