Cod sursa(job #1208637)

Utilizator ZenusTudor Costin Razvan Zenus Data 16 iulie 2014 11:44:23
Problema Robotei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <cstdio>
#include <algorithm>

using namespace std;

#define NMAX 1005
#define DIM 750000
#define PII pair < int , int >

int modX,modY,N,M,offsetX,offsetY,perioada;
PII initial;
int sel[NMAX][NMAX],O[NMAX][NMAX],D[NMAX][NMAX];
int ways[DIM],nextX[NMAX],nextY[NMAX];

void read();
void solve_distanta();
int distanta(int,int);
int Ciclu();
void identice();
void Next();
void write();
void solve();

int main()
{
freopen("robotei.in","r",stdin);
freopen("robotei.out","w",stdout);

read();
Next();
perioada=Ciclu();
solve_distanta();
identice();
solve();
write();

return 0;
}

void Next()
{
    int i;

    for (i=0;i<modX;++i)
    nextX[i]=(i*i+offsetX)%modX;

    for (i=0;i<modY;++i)
    nextY[i]=(i*i+offsetY)%modY;
}

void solve()
{
    int i,j;

    for (i=0;i<modX;++i)
    for (j=0;j<modY;++j)
    {
        if (!D[i][j])
        continue;

        --D[i][j];

        if (!D[i][j] || D[i][j]>M)
        continue;

        D[i][j]=(M-D[i][j])/perioada+1;
    }
    D[initial.first][initial.second]=M/perioada+1;

    for (i=0;i<modX;++i)
    for (j=0;j<modY;++j)
    ways[D[i][j]]+=O[i][j];

    ways[D[initial.first][initial.second]]-=O[initial.first][initial.second]-1;
    ways[D[initial.first][initial.second]-1]+=O[initial.first][initial.second]-1;
}

void write()
{
    int i;

    for (i=0;i<=M;++i)
    {
        if (!ways[i]) continue;
        printf("%d %d\n",i,ways[i]);
    }
}

void solve_distanta()
{
    int i,j;

    D[initial.first][initial.second]=1;
    sel[initial.first][initial.second]=true;

    for (i=0;i<modX;++i)
    for (j=0;j<modY;++j)
    {
        if (sel[i][j]) continue;
        D[i][j]=distanta(i,j);
    }
}

void identice()
{
    int i,j;

    for (i=0;i<modX;++i)
    for (j=0;j<modY;++j)
    O[i][j]=((N-i)/modX+1)*((N-j)/modY+1);
}

int Ciclu()
{
    PII cnt;
    int perioada=1;

    cnt.first=(initial.first*initial.first+offsetX)%modX;
    cnt.second=(initial.second*initial.second+offsetY)%modY;

    while (cnt!=initial && perioada!=(modX*modY))
    {
        cnt.first=nextX[cnt.first];
        cnt.second=nextY[cnt.second];
        ++perioada;
    }

    if (perioada==modX*modY)
    return M+1;

    return perioada;
}

void read()
{
    scanf("%d%d%d%d",&N,&M,&initial.first,&initial.second);
    scanf("%d%d%d%d",&modX,&modY,&offsetX,&offsetY);
    --N;
}


int distanta(int X,int Y)
{
    if (sel[X][Y])
    return D[X][Y];

    sel[X][Y]=true;
    D[X][Y]=distanta(nextX[X],nextY[Y]);

    if (D[X][Y])
    ++D[X][Y];

    return D[X][Y];
}