Cod sursa(job #876209)

Utilizator Theorytheo .c Theory Data 11 februarie 2013 16:10:03
Problema Robotei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.82 kb
#include<fstream>
#include<cstring>

using namespace std;

ifstream fin("robotei.in");
ofstream fout("robotei.out");

#define maxMod 1005

const int NMAX = 1000009;

int N; int M; int ModX; int ModY; int offsetX; int offsetY;

int G[NMAX]; int Solution[NMAX];int WX[maxMod];int WY[maxMod];

bool Visited[NMAX];

struct Node{
    int x; int y; int v;
    Node(){}

    Node(const int x, const int y){
        this -> x = x; this -> y = y;
        v = ModY * x + y;
    }

    Node(const int v){
        this -> x = v / ModY; this -> y = v % ModY;
    }
};

Node Special;
int CycleLength; int Distance[NMAX];


void Read (){

    int X; int Y;
    fin >> N >>M >>X >> Y;
    fin >> ModX >> ModY >> offsetX >> offsetY;

    Special = Node(X, Y);
}

inline int NextX(const int X){

    return (X * X + offsetX) % ModX;
}

inline int NextY(const int Y){

    return (Y * Y + offsetY) % ModY;
}


void BuildGraph(){

    for(int X = 0 ; X < ModX; X++)
        for(int Y = 0 ; Y < ModY; Y++)
            G[Node(X, Y).v] = Node(NextX(X), NextY(Y)).v;
}


void FindCycle() {

    int V = Special.v;

    do{
        Visited[V] = true; ++CycleLength;
        V =  G[V];
    }while(!Visited[V]);

    if(V != Special.v)  CycleLength = NMAX;
}

int getDistance(const int V){

    if(Visited[V])
        return Distance[V];

    Visited[V] = true;
    Distance[V] = getDistance(G[V]);
    Distance[V] += (Distance[V] != -1);

    return Distance[V];
}


void Dist(){

    memset(Distance, -1, sizeof(Distance));
    memset(Visited, 0, sizeof(Visited));

    Visited[Special.v] = true; Distance[Special.v] = 0;

    for(int X = 0 ; X < ModX; ++X)
        for(int Y = 0 ; Y < ModY; ++Y)
            if(!Visited[Node(X, Y).v])
                getDistance(Node(X, Y).v);

}

void Solve () {

     if(Special.x >= ModX || Special.y >= ModY) {
        Solution[0] = N * N - 1; Solution[1] = 1;
        return ;
     }

     BuildGraph ();
     FindCycle ();
     Dist ();

     Special = Node(NextX(Special.x),  NextY(Special.y));
    --M;

    for(int X = 0 ; X < N; ++X){
        ++WX[NextX(X)];++WY[NextY(X)];
    }

    for(int X = 0 ; X < ModX; ++X)
        for(int Y = 0 ;Y < ModY; ++Y){

            int V = Node(X, Y).v; int Frequence = 0 ;
            int Weight = WX[X] * WY[Y] - (Special.y == Y && Special.x == X);
            if(Distance[V] != -1 && M >= Distance[V]){
                Frequence += (1 + (M - Distance[V] )/ CycleLength);

            }
            Solution[Frequence] += Weight;
        }
        ++Solution[1 + (M + 1)/CycleLength];
}

void Print () {

    for(int i = 0 ; i <= M + 1; i++)
        if(Solution[i] > 0)  fout <<i<< " "<<Solution[i] <<'\n';
}
int main(){

    Read ();

    Solve ();

    Print ();
    return 0;
}