Cod sursa(job #1021568)

Utilizator florin.elfusFlorin Elfus florin.elfus Data 3 noiembrie 2013 23:07:09
Problema Robotei Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <stdio.h>
#include <string.h>

int N, M, X, Y, modX, modY, offX, offY;

struct pos {
    int x, y;
};

pos make(int xx, int yy) {
    pos tmp;
    tmp.x = xx; tmp.y = yy;
    return tmp;
}

int get(pos X) {
    return X.x * modY + X.y;
}

int next(int val, int type) {
    if (type == 0)
        return (val * val + offX) % modX;
    return (val * val + offY) % modY;
}

int go[1000000], f[700000], d[1000000], onx[50000], ony[50000];
bool vis[1000100];

void dfs(int nod) {
    if (vis[nod])
        return ;
    vis[nod] = 1;
    dfs(go[nod]);
    d[nod] = d[go[nod]];
    if (d[nod] != -1)
        ++d[nod];
}

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

    scanf("%d%d%d%d%d%d%d%d", &N, &M, &X, &Y, &modX, &modY, &offX, &offY);

    for (int i = 0; i < modX; ++i)
        for (int j = 0; j < modY; ++j)
            go[get(make(i, j))] = get(make(next(i, 0), next(j, 1)));
    if (X >= modX || Y >= modY) {
        f[0] = N * N - 1; f[1] = 1;
    } else {
        int cycle = 0, tmp = get(make(X, Y));
        while (!vis[tmp]) {
            vis[tmp] = 1;
            ++cycle;
            tmp = go[tmp];
        }
        if (tmp != get(make(X, Y)))
            cycle = 1000000000;
        memset(d, -1, sizeof(d));
        memset(vis, 0, sizeof(vis));
        vis[get(make(X, Y))] = 1; d[get(make(X, Y))] = 0;
        for (int i = 0; i < modX; ++i)
            for (int j = 0; j < modY; ++j)
                if (!vis[get(make(i, j))])
                    dfs(get(make(i, j)));
        for (int i = 0; i < N; ++i) {
            ++onx[next(i, 0)];
            ++ony[next(i, 1)];
        }
        --M;
        pos target = make(next(X, 0), next(Y, 1));
        for (int i = 0; i < modX; ++i)
            for (int j = 0; j < modY; ++j) {
                int cnt = onx[i] * ony[j];
                if (i == X && j == Y)
                    --cnt;
                int freq = 0;
                int tmp = get(make(i, j));
                if (!(d[tmp] == -1 || d[tmp] > M))
                    freq = 1 + (M - d[tmp]) / cycle;
                f[freq] += cnt;
            }
        ++f[1 + (M + 1) / cycle];
    }

    for (int i = 0; i <= M; ++i)
        if (f[i])
            printf("%d %d\n", i, f[i]);
    return 0;
}