Cod sursa(job #877943)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 13 februarie 2013 15:23:37
Problema Robotei Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <fstream>
using namespace std;

ifstream fi ("robotei.in");
ofstream fo ("robotei.out");

const int mmax = 666735, modmax = 1002, OO = 1<<30;
int N, M, X, Y, modX, modY, offsetX, offsetY;
int F[mmax], R[modmax][modmax], D[modmax][modmax];

void cit ()
{
    fi >> N >> M >> X >> Y >> modX >> modY >> offsetX >> offsetY;
}

int rec (int x, int y)
{
    if (x == X && y == Y)
        return 0;
    if (D[x][y] == OO || D[x][y] == -1)
        return OO - 1;
    if (D[x][y] != 0)
        return D[x][y];

    D[x][y] = -1;
    D[x][y] = rec ((x * x + offsetX) % modX, (y * y + offsetY) % modY) + 1;
    if (D[x][y] == OO + 1)
        D[x][y] = OO;

    return D[x][y];
}

void pre ()
{
    int x, y, nrx, nry, pozx, pozy;

    for (x = 0; x < modX; x++)
    {
        for (y = 0; y < modY; y++)
        {
            nrx = (N - 1 - x) / modX + 1;
            nry = (N - 1 - y) / modY + 1;
            R[x][y] += nrx * nry;
        }
    }
/*
    for (lungc = 0, pozx = X, pozy = Y; viz[x][y] == 0; lungc++)
    {
        viz[x][y] = 1;

        pozx = (pozx * pozx + offsetX) % modX;
        pozy = (pozy * pozy + offsetY) % modY;
    }
    if ( !(x == X && y == Y) )
        lungc = OO;
*/

    for (x = 0; x < N; x++)
    {
        for (y = 0; y < N; y++)
        {
            if ( (x == X && y == Y) || D[x][y] )
                continue;
            rec (x, y);
        }
    }
    pozx = (X * X + offsetX) % modX;
    pozy = (Y * Y + offsetY) % modY;
    D[X][Y] = D[pozx][pozy] + 1;
}

void rez ()
{
    int x, y, pozx, pozy, m, k;
    for (x = 0; x < modX; x++)
    {
        for (y = 0; y < modY; y++)
        {
/*
            k = 0;
            pozx = x;
            pozy = y;

            for (m = 1; m <= M; m++)
            {
                pozx = (pozx * pozx + offsetX) % modX;
                pozy = (pozy * pozy + offsetY) % modY;

                if (pozx == X && pozy == Y)
                {
                    k++;
                }
            }
*/
            m = M - D[x][y];
            if (m < 0)
                k = 0;
            else
                k = m / D[X][Y] + 1;

            if (x == X && y == Y)
            {
                F[k] += R[x][y] - 1;
                F[k + 1] ++;
            }
            else
            {
                F[k] += R[x][y];
            }
        }
    }
}

void afi ()
{
    if (X >= modX || Y >= modY)
    {
        fo << '0' << ' ' << N * N - 1 << '\n';
        fo << '1' << ' ' << 1 << '\n';
        return;
    }

    for (int m = 0; m <= M; m++)
    {
        if (F[m] == 0)
            continue;
        fo << m << ' ' << F[m] << '\n';
    }
}

int main ()
{
    cit ();
    pre ();
    rez ();
    afi ();

    return 0;
}