Cod sursa(job #1081706)

Utilizator CosminRusuCosmin Rusu CosminRusu Data 13 ianuarie 2014 20:43:16
Problema DreptPal Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <fstream>
#include <vector>
#include <bitset>

using namespace std;

const char infile[] = "dreptpal.in";
const char outfile[] = "dreptpal.out";

ofstream fout(outfile);

const int MAXN = 1005;
const int oo = 0x3f3f3f3f;

typedef vector<int> Graph[MAXN];
typedef vector<int> :: iterator It;

const inline int min(const int &a, const int &b) { if( a > b ) return b;   return a; }
const inline int max(const int &a, const int &b) { if( a < b ) return b;   return a; }
const inline void Get_min(int &a, const int b)    { if( a > b ) a = b; }
const inline void Get_max(int &a, const int b)    { if( a < b ) a = b; }

int A[MAXN][MAXN], N, M, dp[MAXN][MAXN], Stack[MAXN];

inline void buildManacher(int *p, int *DP) {
    int ind = 0, best = 0;
    for(int i = 1 ; i <= M ; ++ i) {
        if(best >= i)
            DP[i] = min(best - i, DP[2*ind - 1]);
        while(i - DP[i] - 1 >= 0 && i + DP[i] + 1 <= M && p[i - DP[i] - 1] == p[i + DP[i] + 1])
            ++DP[i];
        if(i + DP[i] > best) {
            best = i + DP[i];
            ind = i;
        }
    }
}

inline void Solve(void) {
    int Ans = 0;
    for(int j = 1; j <= M ; ++ j) {
        int top = 0;
        for(int i = 1 ; i <= N + 1 ; ++ i) {
            while( top > 0 && dp[i][j] <= dp[Stack[top]][j]) {
                int left = Stack[top - 1] + 1;
                int right = i - 1;
                Ans = max(Ans, (2*dp[Stack[top]][j] + 1) * (right - left + 1));
                -- top;
            }
            Stack[++ top] = i;
        }
    }
    fout << Ans << '\n';
}

class Scanner {
  public:
    Scanner(string file, int buffer_size = 32768):
            buffer_size_(buffer_size) {
        file_ = fopen(file.c_str(), "r");
        buffer_ = new char[buffer_size];
        pointer_ = buffer_ + buffer_size_;
    }

    Scanner& operator>>(int &object) {
        object = 0;
        while (next() < '0' or next() > '9')
            advance();
        while (next() >= '0' and next() <= '9') {
            object = object * 10 + next() - '0';
            advance();
        }
        return *this;
    }

  private:
    char next() {
        if (pointer_ == buffer_ + buffer_size_) {
            pointer_ = buffer_;
            fread(buffer_, 1, buffer_size_, file_);
        }
        return *pointer_;
    }

    void advance() {
        ++pointer_;
    }

    FILE *file_;
    int buffer_size_;
    char *buffer_, *pointer_;
};
Scanner fin(infile);

int main() {
    fin >> N >> M;
    for(int i = 1 ; i <= N ; ++ i)
        for(int j = 1 ; j <= M ; ++ j)
            fin >> A[i][j];
    for(int i = 1 ; i <= N ; ++ i)
        buildManacher(A[i], dp[i]);
    Solve();
    return 0;
}