Cod sursa(job #851894)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 10 ianuarie 2013 16:35:27
Problema Robotei Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.98 kb
#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int MaxN = 1000005;
const int MaxC = 1005;

int N, M, ModX, ModY, OffsetX, OffsetY;

struct Node {
    int x, y, 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;
vector<int> GT[MaxN];
int G[MaxN], CycleLength, Distance[MaxN], WX[MaxC], WY[MaxC], Solution[MaxN];
bool InCycle[MaxN];
queue<int> Q;

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;
            GT[G[Node(X, Y).v]].push_back(Node(X, Y).v);
        }
    }
}

void FindCycle() {
    int Fast = Special.v, Slow = Special.v;
    do {
        Slow = G[Slow], Fast = G[G[Fast]];
    } while (Fast != Slow);
    do {
        InCycle[Fast = G[Fast]] = true, ++CycleLength;
    } while (Fast != Slow);
    if (!InCycle[Special.v])
        CycleLength = MaxN;
}

inline void InitBFS(const int Source) {
    memset(Distance, -1, sizeof(Distance));
    Distance[Source] = 0, Q.push(Source);
}

void BFS(const int Source) {
    for (InitBFS(Source); !Q.empty(); Q.pop()) {
        int X = Q.front();
        for (vector<int>::iterator Y = GT[X].begin(); Y != GT[X].end(); ++Y)
            if (Distance[*Y] == -1)
                Distance[*Y] = Distance[X] + 1, Q.push(*Y);
    }
}

void Solve() {
    if (Special.x >= ModX || Special.y >= ModY) {
        Solution[0] = N * N - 1, Solution[1] = 1;
        return;
    }
    BuildGraph();
    FindCycle();
    BFS(Special.v);
    Special = Node(NextX(Special.x), NextY(Special.y));
    --M;
    for (int V = 0; V < N; ++V)
        ++WX[NextX(V)], ++WY[NextY(V)];
    for (int X = 0; X < ModX; ++X) {
        for (int Y = 0; Y < ModY; ++Y) {
            int Weight = WX[X] * WY[Y] - (Special.x == X && Special.y == Y);
            int V = Node(X, Y).v, Frequence = 0;
            if (Distance[V] != -1 && M >= Distance[V])
                Frequence += (1 + (M - Distance[V]) / CycleLength);
            Solution[Frequence] += Weight;
        }
    }
    ++Solution[1 + (M + 1) / CycleLength];
}

void Read() {
    assert(freopen("robotei.in", "r", stdin));
    int X, Y; assert(scanf("%d %d %d %d", &N, &M, &X, &Y) == 4);
    assert(scanf("%d %d %d %d", &ModX, &ModY, &OffsetX, &OffsetY) == 4);
    Special = Node(X, Y);
}

void Print() {
    assert(freopen("robotei.out", "w", stdout));
    for (int i = 0; i <= M + 1; ++i)
        if (Solution[i] > 0)
            printf("%d %d\n", i, Solution[i]);
}

int main() {
    Read();
    Solve();
    Print();
    return 0;
}