Cod sursa(job #1653783)

Utilizator rughibemBelcineanu Alexandru Ioan rughibem Data 16 martie 2016 16:10:05
Problema Robotei Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
#include<stdio.h>
#include<algorithm>
#include<vector>
#define MAXN 44400
#define MAXM 666800
#define MAXmod 1005
#define INF 2000000000
#define lli long long int
FILE *f=fopen("robotei.in","r"), *g=fopen("robotei.out","w");

using namespace std;

vector <int> v[ MAXmod * MAXmod ];

int N, M, X, Y, modX, modY, plusX, plusY, Ciclu;
int Pasi[ MAXmod * MAXmod ], Qcod[ MAXmod * MAXmod ], Qpasi[ MAXmod * MAXmod ];
int SOL[MAXM], nextX[MAXmod], nextY[MAXmod];

int NextX( int x ){ lli R = ( (1LL*x) * (1LL*x) + (1LL*plusX) ) % (1LL*modX); return ((int)R); }

int NextY( int y ){ lli R = ( (1LL*y) * (1LL*y) + (1LL*plusY) ) % (1LL*modY); return ((int)R); }

int Codif( int i, int j ){ return i * modY + j; }

void Initializari(){
int i;

    for(i=0;i<=modX-1;i++)
        nextX[i] = NextX(i);

    for(i=0;i<=modY-1;i++)
        nextY[i] = NextY(i);

    for(i=0;i<=modX*modY-1;i++)
        Pasi[i] = INF;

}

void AflaCiclu(){
int x, y;

    Ciclu = 1;
    x = NextX(X);
    y = NextY(Y);

    while( !( x == X && y == Y ) && Ciclu <= M ){

        x = nextX[x];
        y = nextY[y];
        Ciclu ++;

    }

}

void CreareV(){
int i, j;

    for(i=0;i<=modX-1;i++)
        for(j=0;j<=modY-1;j++)
            v[ Codif( nextX[i], nextY[j] ) ].push_back( Codif( i, j ) );
}

void BFS(){
int i, st, fn, cod, pasi, NEWcod;

    Qcod [1] = Codif(X,Y);
    Qpasi[1] = 0;
    Pasi[ Codif(X,Y) ] = 0;

    st = 1; fn = 1;

    while( st <= fn ){

        cod  = Qcod [st];
        pasi = Qpasi[st];

        for(i=0;i<v[cod].size();i++){

            NEWcod = v[cod][i];

            if( Pasi[NEWcod] == INF && pasi + 1 <= M ){

                fn++;
                Qcod [fn] = NEWcod;
                Qpasi[fn] = pasi+1;
                Pasi[ NEWcod ] = pasi+1;

            }

        }


        st++;
    }

}

void Rezolvare(){
int i, j, Atins, solX, solY;

    // solX = nr solutii x % modX = i, adica  i + modX * K C[0,N-1]

    for(i=0;i<=modX-1;i++)
        for(j=0;j<=modY-1;j++){

            if( Pasi[ Codif(i,j) ] <= M )
                Atins = 1 + ( M - Pasi[ Codif(i,j) ] ) / Ciclu;

            else
                Atins = 0;

            SOL[Atins] ++;

            solX = ( N-1 - i ) / modX;
            solY = ( N-1 - j ) / modY;

            if( i == X && j == Y )
                SOL[Atins-1] += ( (solX+1) * (solY+1) - 1 ); // -1, pt ca am adaugat deja sus
            else
                SOL[Atins  ] += ( (solX+1) * (solY+1) - 1 );
        }

    for(i=0;i<=M;i++)
        if( SOL[i] != 0 )
            fprintf(g,"%d %d\n",i,SOL[i]);

}

int main(){

    fscanf(f,"%d %d %d %d %d %d %d %d\n",&N,&M,&X,&Y,&modX,&modY,&plusX,&plusY);

    if( !( X <= modX-1 && Y <= modY-1 ) ){ fprintf(g,"0 %d\n1 1\n",N*N-1); return 0; }

    Initializari();
    AflaCiclu();

    CreareV();

    BFS();

    Rezolvare();

return 0;
}