Cod sursa(job #741526)

Utilizator dushmiMihai-Alexandru Dusmanu dushmi Data 26 aprilie 2012 12:18:11
Problema Rsir Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.46 kb
#include <cstdio>
#include <utility>

using namespace std;

const int kMaxM = 7005;

int a, b, x, y, z, T0, T1, M, p2[kMaxM], v1[kMaxM], v2[kMaxM];

long long n;

void next(pair <int, int> &a) {
  int x = v1[a.first] + v2[a.second];
  if (x >= M)
    x -= M;
  
  a.second = a.first;
  a.first = x;
}

void read() {
  scanf("%d%d%d%d%d%d%d%d%lld", &T0, &T1, &a, &b, &x, &y, &z, &M, &n);
  T0 %= M;
  T1 %= M;
}

void init() {
  for (int i = 0; i < M; ++i)
    p2[i] = (i * i) % M;

  for (int i = 0; i < M; ++i)
    v1[i] = (b * p2[i] + y * i) % M;

  for (int i = 0; i < M; ++i)
    v2[i] = (a * p2[i] + x * i + z) % M;
}

inline int min(int x, int y) {
  return x < y ? x : y;
}

void solve() {
  pair <int, int> p1, p2;

  p1.first = p2.first = T1;
  p1.second = p2.second = T0;

  do {
    next(p1);
    next(p2); next(p2);
  } while (p1 != p2);

  // determin lungimea ciclului
  int lciclu = 0;

  do {
    next(p2);
    ++lciclu;
  } while (p1 != p2);

  // determin lungimea unei cozi posibile 
  int lcoada = 0;

  p2.first = T1;
  p2.second = T0;
  
  while (p1 != p2) {
    next(p2);
    ++lcoada;
  }

  // rezolv
  p2.first = T1;
  p2.second = T0;

  --n;

  for (int i = 1; i <= min(n, lcoada); ++i)
    next(p2);

  n -= 1LL * lcoada;
  if (n > 0) {
    n %= lciclu;
    for (int i = 1; i <= n; ++i)
      next(p2);
  }

  printf("%d\n", p2.first);
}

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

  read();

  init();

  solve();

  return 0;
}