Cod sursa(job #1160501)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 30 martie 2014 16:24:17
Problema Curcubeu Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <iostream>
#include <fstream>
#include <vector>

//#define __DEBUG

std::vector<int> a, b, c;

struct Node {
  Node* left, *right;
  int span;
  int filled;
  int color; // Only filled in if homogenous.

  Node(Node* left, Node* right, int span, int filled)
      : left(left), right(right), span(span), filled(filled), color(0) {}
};

Node* make_tree(int li, int lf) {
  if (li == lf) {
    return new Node(NULL, NULL, lf - li + 1, 0);
  } else {
    return new Node(make_tree(li, (li + lf) / 2),
                    make_tree(((li + lf) / 2) + 1, lf),
                    lf - li + 1,
                    0);
  }
}

void color_tree(Node* root, int li, int lf, int a, int b, int c) {
#ifdef __DEBUG
  std::cerr << "Coloring node (" << li << ", " << lf << ") with interval "
      << "(" << a << ", " << b << "), and color <" << c << ">." << std::endl;
#endif

  int m = (li + lf) / 2;
  if (a > li || b < lf) {
    // Check that (a, b) is strictly included in (li, lf).
    if (a <= m) {
#ifdef __DEBUG
      std::cerr << "Recursing on left." << std::endl;
#endif
      color_tree(root->left,  li,    m,  a, std::min(b, m), c);
    }
    if (b >= m + 1) {
#ifdef __DEBUG
      std::cerr << "Recursing on right." << std::endl;
#endif
      color_tree(root->right, m + 1, lf, std::max(a, m + 1), b, c);
    }

    root->filled = root->left->filled + root->right->filled;
    return;
  }

  // Now we know that (a == li, b == lf).
  if (root->filled == root->span) {
    // Give up if there is nothing to color.
#ifdef __DEBUG
    std::cerr << "Already colored." << std::endl;
#endif
    return;
  } else if (root->filled == 0) {
#ifdef __DEBUG
    std::cerr << "Coloring with <" << c << ">." << std::endl;
#endif
    // Color everything if the root is empty.
    root->color = c;
    root->filled = root->span;
    return;
  } else {
#ifdef __DEBUG
    std::cerr << "Breaking up the coloring because it's patchy." << std::endl;
#endif
    color_tree(root->left,  li,    m,  a,     m, c);
    color_tree(root->right, m + 1, lf, m + 1, b, c);
    root->filled = root->left->filled + root->right->filled;
    return;
  }
}

void flatten_tree(Node* root, int li, int lf, std::ostream& out)
{
  if (root->color != 0 || root->filled == 0) {
    // If it's either a color, or the root is empty, then print the color.
    for (int i = li; i <= lf; ++i) {
      out << root->color << std::endl;
    }
  } else {
    // If color is 0 and root is not filled, break it up.
    flatten_tree(root->left, li, (li + lf) / 2, out);
    flatten_tree(root->right, (li + lf) / 2 + 1, lf, out);
  }
}

int main()
{
  std::ifstream in("curcubeu.in");
  int n, a1, b1, c1;
  in >> n >> a1 >> b1 >> c1;
  in.close();
  a.push_back(std::min(a1, b1));
  b.push_back(std::max(a1, b1));
  c.push_back(c1);
  for (int i = 2; i < n; ++i) {
    a1 = (a1 * i) % n;
    b1 = (b1 * i) % n;
    c1 = (c1 * i) % n;
    a.push_back(std::min(a1, b1));
    b.push_back(std::max(a1, b1));
    c.push_back(c1);
  }

  Node* root = make_tree(1, n - 1);
  for (int i = c.size() - 1; i >= 0; --i) {
    color_tree(root, 1, n - 1, a[i], b[i], c[i]);
  }

  std::ofstream out("curcubeu.out");
//  flatten_tree(root, 1, n - 1, out);
  out.close();

  return 0;
}