Cod sursa(job #2966384)

Utilizator AndreiDenisAndrei Denis AndreiDenis Data 17 ianuarie 2023 13:28:52
Problema Algoritmul lui Euclid extins Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("euclid.in");
ofstream out("euclid.out");

int a[401][401];

int A[1605][1605];

int n, m, h, w;

void build_y(int vx, int lx, int rx, int vy, int ly, int ry)
{
    if(ly == ry)
    {
        if(lx == rx)
          A[vx][vy] = a[lx][ly];
        else
          A[vx][vy] = __gcd(A[vx * 2][vy], A[vx * 2 + 1][vy]);
    }
    else
    {
        int my = (ly + ry) / 2;
        build_y(vx, lx, rx, vy * 2, ly, my);
        build_y(vx, lx, rx, vy * 2 + 1, my + 1, ry);
        A[vx][vy] = __gcd(A[vx][vy * 2], A[vx][vy * 2 + 1]);
    }
}

void build_x(int vx, int lx, int rx)
{
    if(lx != rx)
    {
        int mx = (lx + rx) / 2;
        build_x(vx * 2, lx, mx);
        build_x(vx * 2 + 1, mx + 1, rx);
    }
    build_y(vx, lx, rx, 1, 1, m);
}

int gcd_y(int vx, int vy, int tly, int try_, int ly, int ry)
{
    if(ly > ry)
        return 0;
    if(ly == tly && try_ == ry)
        return A[vx][vy];
    int my = (tly + try_) / 2;
    return __gcd(gcd_y(vx, vy * 2, tly, my, ly, min(ry, my)), gcd_y(vx, vy * 2 + 1, my + 1, try_, max(ly, my + 1), ry));
}

int gcd_x(int vx, int tlx, int trx, int lx, int rx, int ly, int ry)
{
    if(lx > rx)
        return 0;
    if(lx == tlx && trx == rx)
        return gcd_y(vx, 1, 1, m, ly, ry);
    int mx = (tlx + trx) / 2;
    return __gcd(gcd_x(vx*2, tlx, mx, lx, min(rx, mx), ly, ry), gcd_x(vx*2+1, mx+1, trx, max(lx, mx+1), rx, ly, ry));
}

int main()
{
    int t;
    in >> t;
    for(int te = 1; te <= t; te++)
    {
        in >> n >> m >> h >> w;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                in >> a[i][j];
            }
        }
        build_x(1, 1, n);
        int maxim = 0;
        for(int i = 1; i <= n - h + 1; i++)
        {
            for(int j = 1; j <= m - w + 1; j++)
            {
               // cmmdc : i, j, i + h, j + w
               maxim = max(maxim, gcd_x(1, 1, n, i, j, i + h - 1, j + w - 1));
            }
        }
        out << "Case #" << te << ": " << maxim << '\n';
    }
    return 0;
}