Cod sursa(job #1653762)

Utilizator rughibemBelcineanu Alexandru Ioan rughibem Data 16 martie 2016 15:54:45
Problema Robotei Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.54 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 ], 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 DFS( int Cod, int pasi ){
int i;

    if( Pasi[Cod] != INF )
        return;

    if( pasi > M )
        return;

    Pasi[Cod] = pasi;

    for(i=0;i<v[Cod].size();i++)
        DFS( v[Cod][i], pasi+1 );

}

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();

    DFS( Codif(X,Y) ,0);

    Rezolvare();

return 0;
}