Sunday, January 24, 2016

UVa 517 - Word

Accepted date: 2016-01-24
Run Time: 0.009
Ranking (as of 2016-01-24): 13 out of 544
Language: C++

/*
  UVa 517 - Word

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_517_Word.cpp
*/

#include <algorithm>
#include <cstdio>
using namespace std;

const int nr_chars_max = 15, nr_rules = 8, nr_words_max = 1 << nr_chars_max;

int visited[nr_words_max];
int nr_words, words[nr_words_max];

int word_to_value(int word, int wi, int length)
{
  int value = 0;
  for (int i = 0, b = 1 << (length - 1);
    i < length; i++, b >>= 1, wi = (wi - 1 + length) % length)
    if (word & (1 << wi))
      value += b;
  return value;
}

int get_min_word(int word, int length)
{
  int min_word = 1 << length;
  for (int i = 0; i < length; i++)
    min_word = min(min_word, word_to_value(word, i, length));
  return min_word;
}

void print_word(int word, int length)
{
  for (int i = 0, b = 1 << (length - 1); i < length; i++, b >>= 1)
    putchar((word & b) ? 'b' : 'a');
  putchar('\n');
}

struct rule {
  int c1_, c2_, c3_, c4_;
};

int main()
{
  int length, steps;
  char s[nr_chars_max + 1];
  rule rules[nr_rules];
  while (scanf("%d", &length) != EOF) {
    for (int i = 0, j = 1 << length; i < j; i++)
      visited[i] = -1;
    nr_words = 0;
    scanf("%s", s);
    int word = 0, next_word;
    for (int i = 0, b = 1 << (length - 1); i < length; i++, b >>= 1)
      if (s[i] == 'b')
        word += b;
    word = get_min_word(word, length);
    for (int i = 0; i < nr_rules; i++) {
      scanf("%s", s);
      rules[i].c1_ = (s[0] == 'b') ? 1 : 0;
      rules[i].c2_ = (s[1] == 'b') ? 1 : 0;
      rules[i].c3_ = (s[2] == 'b') ? 1 : 0;
      rules[i].c4_ = (s[3] == 'b') ? 1 : 0;
    }
    scanf("%d", &steps);
    int cycle_start = -1, cycle_length = 0;
    for (int i = 0; i < steps; i++) {
      int next_word = word;
      for (int j = 0; j < nr_rules; j++) {
        const rule& r = rules[j];
        for (int k = 0; k < length; k++) {
          int k1 = (k + 2) % length, k3 = (k - 1 + length) % length;
          if ((word & (1 << k1)) >> k1 == r.c1_ &&
            (word & (1 << k)) >> k == r.c2_ &&
            (word & (1 << k3)) >> k3 == r.c3_) {
            if (r.c4_)
              next_word |= 1 << k;
            else
              next_word &= ~(1 << k);
          }
        }
      }
      word = get_min_word(next_word, length);
      if (visited[word] != -1) {
        cycle_start = visited[word];
        cycle_length = nr_words - cycle_start;
        break;
      }
      else {
        visited[word] = nr_words;
        words[nr_words++] = word;
      }
    }
#ifdef DEBUG
    printf("%d\n", nr_words);
    for (int i = 0; i < nr_words; i++)
      print_word(words[i], length);
#endif
    if (nr_words < steps) {
#ifdef DEBUG
      printf("%d %d\n", cycle_start, cycle_length);
#endif
      word = words[cycle_start + (steps - cycle_start - 1) % cycle_length];
    }
    print_word(word, length);
  }
  return 0;
}

Wednesday, January 20, 2016

UVa 257 - Palinwords

Accepted date: 2016-01-20
Run Time: 0.003
Ranking (as of 2016-01-20): 10 out of 449
Language: C++

/*
  UVa 257 - Palinwords

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_257_Palinwords.cpp
*/

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

bool is_palindrome(const char* s, int i, int j)
{
  for ( ; i < j; i++, j--)
    if (s[i] != s[j])
      return false;
  return true;
}

bool is_embedded(const char* s, int i, int j, int ei, int el)
{
  for ( ; i < j - el + 2; i++)
    if (!strncmp(s + i, s + ei, el))
      return true;
  return false;
}

bool is_palinword(const char* s, int length)
{
  int i, j, pi = -1 ,pj = -1, l, pl;
  for (i = 0; i < length - 3 + 1; i++) {
    j = i + 2;
    if (pj != -1 && pj >= j)
      j++;
#ifdef ONLINE_JUDGE // for some unknown reasons
    for ( ; j < min(i + 4, length); j++)
#else
    for ( ; j < length; j++)
#endif
      if (is_palindrome(s, i, j)) {
#ifdef DEBUG
        printf("%d %d: ", i, j);
        for (int k = i; k <= j; k++)
          putchar(s[k]);
        putchar('\n');
#endif
        if (pi == -1) // first one found
          pi = i, pj = j, pl = pj - pi + 1;
        else {
          l = j - i + 1;
          if (l < pl) {
            if (!is_embedded(s, pi, pj, pi, l))
              return true;
          }
          else {
            if (!is_embedded(s, i, j, pi, pl))
              return true;
          }
          pi = i, pj = j, pl = pj - pi + 1;
        }
        break;
      }
  }
  return false;
}

int main()
{
  const int nr_chars_max = 255;
  char s[nr_chars_max + 1];
  while (scanf("%s", s) != EOF) {
    if (is_palinword(s, strlen(s)))
      puts(s);
  }
  return 0;
}

Saturday, January 16, 2016

UVa 10765 - Doves and bombs

Accepted date: 2016-01-16
Run Time: 0.009
Ranking (as of 2016-01-16): 64 out of 547
Language: C++

/*
  UVa 10765 - Doves and bombs

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_10765_Doves_and_bombs.cpp
*/

#include <algorithm>
#include <vector>
#include <cstdio>
using namespace std;

const int n_max = 10000;
vector<int> edges[n_max];

struct state {
  bool visited_;
  int parent_;
  int discovery_;
  int earliest_;
    // time of earliest visited vertex reachable from the subtree 
    // rooted with this vertex

  state() : parent_(-1), discovery_(-1), earliest_(-1) {}
} states[n_max];

struct pigeon_value {
  int i_, values_;

bool operator<(const pigeon_value& pv) const {
  return (values_ != pv.values_) ? values_ > pv.values_ : i_ < pv.i_;
}
} pigeon_values[n_max];

void find_articulation_points(int u, int t)
{
  states[u].visited_ = true;
  states[u].discovery_ = states[u].earliest_ = t;
  const vector<int>& es = edges[u];
  int nr_children = 0;
  for (size_t i = 0, e = es.size(); i < e; i++) {
    int v = es[i];
    if (!states[v].visited_) {
      nr_children++;
      states[v].parent_ = u;
      find_articulation_points(v, t + 1);

      states[u].earliest_  = min(states[u].earliest_, states[v].earliest_);
      if (states[u].parent_ == -1 && nr_children > 1 ||
        states[u].parent_ != -1 && states[v].earliest_ >= states[u].discovery_) {
#ifdef DEBUG
        printf("articulation point = %d\n", u);
#endif
        pigeon_values[u].values_++;
      }
    }
    else if (v != states[u].parent_)
      states[u].earliest_  = min(states[u].earliest_, states[v].discovery_);
  }
#ifdef DEBUG
  printf("%d: parent = %d, discovery = %d, earliest = %d\n", u,
    states[u].parent_, states[u].discovery_, states[u].earliest_);
#endif
}

int main()
{
  while (true) {
    int n, m;
    scanf("%d %d", &n, &m);
    if (!n)
      break;
    for (int i = 0; i < n; i++) {
      edges[i].clear();
      states[i].visited_ = false;
      states[i].parent_ = states[i].discovery_ = states[i].earliest_ = -1;
      pigeon_values[i].i_ = i;
      pigeon_values[i].values_ = 1;
    }
    while (true) {
      int x, y;
      scanf("%d %d", &x, &y);
      if (x == -1)
        break;
      edges[x].push_back(y);
      edges[y].push_back(x);
    }
    find_articulation_points(0, 0);
    sort(pigeon_values, pigeon_values + n);
    for (int i = 0; i < m; i++)
      printf("%d %d\n", pigeon_values[i].i_, pigeon_values[i].values_);
    putchar('\n');
  }
  return 0;
}

Thursday, January 14, 2016

UVa 11935 - Through the Desert

Accepted date: 2016-01-14
Run Time: 0.000
Ranking (as of 2016-01-14): 63 out of 622
Language: C++

/*
  UVa 11935 - Through the Desert

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_11935_Through_the_Desert.cpp
*/

#include <algorithm>
#include <cstdio>
using namespace std;

int main()
{
  double distance_per_litre = 100.0;
  while (true) {
    int p, n;
    const int nr_chars_max = 15;
    char s[nr_chars_max + 1];
    scanf("%d %s %*s %d", &p, s, &n);
    if (!n)
      break;
    int pp = p, l = 0;
    double tank = 0.0, max_tank = 0.0;
    bool goal = false;
    do {
      scanf("%d %s", &p, s);
      int d = p - pp;
      pp = p;
      tank += d / distance_per_litre * n + d * l;
      max_tank = max(max_tank, tank);
      switch (s[0]) {
      case 'F': // "Fuel"
        scanf("%*s %d", &n);
        break;
      case 'L':
        l++;
        break;
      case 'G':
        if (s[1] == 'a') {
          scanf("%*s");
          tank = 0.0;
        }
        else
          goal = true;
        break;
      case 'M':
        l = 0;
        break;
      }
    } while (!goal);
    printf("%.3lf\n", max_tank);
  }
  return 0;
}

Wednesday, January 13, 2016

UVa 610 - Street Directions

Accepted date: 2016-01-13
Run Time: 0.049
Ranking (as of 2016-01-13): 159 out of 950
Language: C++

/*
  UVa 610 - Street Directions

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_610_Street_Directions.cpp
*/

#include <algorithm>
#include <vector>
#include <utility>
#include <cstdio>
using namespace std;

const int n_max = 1000;

vector<int> edges[n_max + 1];
bool bridges[n_max + 1][n_max + 1];
  // bridges[u][v] is true if an edge u - v (u < v) is a bridge

struct state {
  bool visited_;
  int parent_;
  int discovery_; // discovery time
  int earliest_;
    // time of earliest visited vertex reachable from the subtree 
    // rooted with this vertex

  state() : visited_(false), parent_(-1), discovery_(-1), earliest_(-1) {}
} states[n_max + 1];

void find_bridges(int u, int t)
{
  states[u].visited_ = true;
  states[u].discovery_ = states[u].earliest_ = t;
  const vector<int>& es = edges[u];
  for (size_t i = 0, e = es.size(); i < e; i++) {
    int v = es[i];
    if (!states[v].visited_) {
      states[v].parent_ = u;
      find_bridges(v, t + 1);

      states[u].earliest_  = min(states[u].earliest_, states[v].earliest_);
      if (states[v].earliest_ > states[u].discovery_) {
        bridges[min(u, v)][max(u, v)] = true;
#ifdef DEBUG
        printf("bridge: %d - %d\n", min(u, v), max(u, v));
#endif
      }
    }
    else if (v != states[u].parent_)
      states[u].earliest_  = min(states[u].earliest_, states[v].discovery_);
  }
#ifdef DEBUG
  printf("%d: parent = %d, discovery = %d, earliest = %d\n", u,
    states[u].parent_, states[u].discovery_, states[u].earliest_);
#endif
}

int main()
{
  for (int cn = 1; ; cn++) {
    int n, m;
    scanf("%d %d", &n, &m);
    if (!n && !m)
      break;
    for (int i = 1; i <= n; i++) {
      edges[i].clear();
      states[i].visited_ = false;
      states[i].parent_ = states[i].discovery_ = states[i].earliest_ = -1;
      for (int j = i + 1; j <= n; j++)
        bridges[i][j] = false;
    }
    while (m--) {
      int i, j;
      scanf("%d %d", &i, &j);
      edges[i].push_back(j);
      edges[j].push_back(i);
    }
    find_bridges(1, 0);
    printf("%d\n\n", cn);
#ifdef __SORTED_LIST__
    vector< pair<int, int> > streets;
    for (int u = 1; u <= n; u++) {
      const vector<int>& es = edges[u];
      for (size_t i = 0, e = es.size(); i < e; i++) {
        int v = es[i];
        if (u < v) {
          bool b = bridges[u][v];
          if (states[v].parent_ == u) {
            streets.push_back(make_pair(u, v));
            if (b)
              streets.push_back(make_pair(v, u));
          }
          else if (states[u].parent_ == v) {
            streets.push_back(make_pair(v, u));
            if (b)
              streets.push_back(make_pair(u, v));
          }
          else if (states[v].discovery_ < states[u].discovery_)
            streets.push_back(make_pair(u, v));
          else
            streets.push_back(make_pair(v, u));
        }
      }
    }
    sort(streets.begin(), streets.end());
    for (vector< pair<int, int> >::const_iterator i = streets.begin(),
      e = streets.end(); i != e; i++)
      printf("%d %d\n", i->first, i->second);
#else
    for (int u = 1; u <= n; u++) {
      const vector<int>& es = edges[u];
      for (size_t i = 0, e = es.size(); i < e; i++) {
        int v = es[i];
        if (u < v) {
          bool b = bridges[u][v];
          if (states[v].parent_ == u) {
            printf("%d %d\n", u, v);
            if (b)
              printf("%d %d\n", v, u);
          }
          else if (states[u].parent_ == v) {
            printf("%d %d\n", v, u);
            if (b)
              printf("%d %d\n", u, v);
          }
          else if (states[v].discovery_ < states[u].discovery_)
            printf("%d %d\n", u, v);
          else
            printf("%d %d\n", v, u);
        }
      }
    }
#endif
    puts("#");
  }
  return 0;
}

Monday, January 11, 2016

UVa 668 - Parliament

Accepted date: 2016-01-11
Run Time: 0.000
Ranking (as of 2016-01-11): 163 out of 518
Language: C++

/*
  UVa 668 - Parliament

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_668_Parliament.cpp
*/

#include <cstdio>
#include <cstring>

/*
4
 5: 2 3
 6: 2 4
 7: 3 4
 8: 3 5

5
 9: 2 3 4                5: + 4
10: 2 3 5                5: + 5
11: 2 4 5                6: + 5
12: 3 4 5                7: + 5
13: 3 4 6                7: + 6

6
14: 2 3 4 5              9: + 5
15: 2 3 4 6              9: + 6
16: 2 3 5 6             10: + 6
17: 2 4 5 6             11: + 6
18: 3 4 5 6             12: + 6
19: 3 4 5 7             12: + 7

7
20: 2 3 4 5 6           14: + 6
21: 2 3 4 5 7           14: + 7
22: 2 3 4 6 7           15: + 7
23: 2 3 5 6 7           16: + 7
24: 2 4 5 6 7           17: + 7
25: 3 4 5 6 7           18: + 7
26: 3 4 5 6 8           18: + 8

8
27: 2 3 4 5 6 7         20: + 7
28: 2 3 4 5 6 8         20: + 8
29: 2 3 4 5 7 8         21: + 8
30: 2 3 4 6 7 8         22: + 8
31: 2 3 5 6 7 8         23: + 8
32: 2 4 5 6 7 8         24: + 8
33: 3 4 5 6 7 8         25: + 8
34: 3 4 5 6 7 9         25: + 9

9
35: 2 3 4 5 6 7 8       27: + 8
36: 2 3 4 5 6 7 9       27: + 9
37: 2 3 4 5 6 8 9       28: + 9
38: 2 3 4 5 7 8 9       29: + 9
39: 2 3 4 6 7 8 9       30: + 9
40: 2 3 5 6 7 8 9       31: + 9
41: 2 4 5 6 7 8 9       32: + 9
42: 3 4 5 6 7 8 9       33: + 9
43: 3 4 5 6 7 8 10      33: + 10
...
*/

const int N_min = 5, N_max = 1000, nr_sizes_max = 45;
int nr_sizes[N_max + 1] = {
  0, 0, 0, 0, 0,
  2, 2, 2, 2
};
int sizes[N_max + 1][nr_sizes_max] = {
  {0}, {0}, {0}, {0}, {0},
  {2, 3}, {2, 4}, {3, 4}, {3, 5}
};

int main()
{
  for (int nr = N_min, pnr = N_min - 1, n = nr + pnr; n <= N_max; pnr = nr++) {
#ifdef DEBUG
    printf("%d\n", nr);
#endif
    for (int i = 0; i < nr && n <= N_max; i++, n++) {
      if (!i) {
        memcpy(sizes[n], sizes[n - pnr], nr_sizes[n - pnr] * sizeof(int));
        sizes[n][nr_sizes[n - pnr]] = pnr;
        nr_sizes[n] = nr_sizes[n - pnr] + 1;
      }
      else if (i == nr - 1) {
        memcpy(sizes[n], sizes[n - pnr - 2], nr_sizes[n - pnr - 2] * sizeof(int));
        sizes[n][nr_sizes[n - pnr - 2]] = nr + 1;
        nr_sizes[n] = nr_sizes[n - pnr - 2] + 1;
      }
      else {
        memcpy(sizes[n], sizes[n - pnr - 1], nr_sizes[n - pnr - 1] * sizeof(int));
        sizes[n][nr_sizes[n - pnr - 1]] = nr;
        nr_sizes[n] = nr_sizes[n - pnr - 1] + 1;
      }
#ifdef DEBUG
      printf("%4d: ", n);
      for (int j = 0; j < nr_sizes[n]; j++)
        printf("%d%c", sizes[n][j], ((j < nr_sizes[n] - 1) ? ' ' : '\n'));
#endif
    }
  }

  int M;
  scanf("%d", &M);
  while (M--) {
    int N;
    scanf("%d", &N);
    for (int j = 0; j < nr_sizes[N]; j++)
      printf("%d%c", sizes[N][j], ((j < nr_sizes[N] - 1) ? ' ' : '\n'));
    if (M)
      putchar('\n');
  }
  return 0;
}

Wednesday, January 6, 2016

UVa 671 - Spell checker

Accepted date: 2016-01-06
Run Time: 0.036
Ranking (as of 2016-01-06): 6 out of 525
Language: C++

/*
  UVa 671 - Spell checker

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_671_Spell_checker.cpp
*/

#include <cstdio>
#include <cstring>

const int nr_words_max = 10000, nr_chars_max = 15;
char words[nr_words_max + 1][nr_chars_max + 1];
int replaceables[nr_words_max];

int correct_or_replaceable(const char* w, const char* s)
{
  while (*w && *s && *w == *s)
    w++, s++;
  if (!*w && !*s)
    return 1; // correct
  else if (!strcmp(w + 1, s) || !strcmp(w, s + 1) || !strcmp(w + 1, s + 1))
    return 0;
  else
    return -1;
}

int main()
{
  int N;
  scanf("%d", &N);
  while (N--) {
    int nr_words = 0;
    while (true) {
      scanf("%s", words[nr_words]);
      if (words[nr_words][0] == '#')
        break;
      nr_words++;
    }
    while (true) {
      char s[nr_chars_max + 1];
      scanf("%s", s);
      if (s[0] == '#')
        break;
      int correct = -1, nr_replaceables = 0;
      for (int i = 0; i < nr_words; i++) {
        int cr = correct_or_replaceable(words[i], s);
        if (cr == 1) { // correct
          correct = i;
          break;
        }
        else if (cr == 0) // replaceable
          replaceables[nr_replaceables++] = i;
      }
      if (correct != -1)
        printf("%s is correct\n", s);
      else {
        printf("%s:", s);
        for (int i = 0; i < nr_replaceables; i++)
          printf(" %s", words[replaceables[i]]);
        putchar('\n');
      }
    }
    if (N)
      putchar('\n');
  }
  return 0;
}

Tuesday, January 5, 2016

UVa 10870 - Recurrences

Accepted date: 2016-01-05
Run Time: 0.019
Ranking (as of 2016-01-05): 27 out of 660
Language: C++

/*
  UVa 10870 - Recurrences

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_10870_Recurrences.cpp
*/

#include <cstdio>

const int d_max = 15;

void identity_matrix(int d, int a[d_max + 1][d_max + 1])
{
  for (int i = 1; i <= d; i++)
    for (int j = 1; j <= d; j++)
            a[i][j] = (i == j) ? 1 : 0;
}

void matrix_multiply(int d, int m, int ma[d_max + 1][d_max + 1],
  int mb[d_max + 1][d_max + 1])
{
  int result[d_max + 1][d_max + 1];
  for (int i = 1; i <= d; i++)
    for (int j = 1; j <= d; j++) {
      int r = 0;
            for (int k = 1; k <= d; k++) {
        r += ma[i][k] * mb[k][j] % m;
        r %= m;
      }
      result[i][j] = r;
    }
  for (int i = 1; i <= d; i++)
    for (int j = 1; j <= d; j++)
      ma[i][j] = result[i][j];
}

void matrix_power(int d, int n, int m, int matrix[d_max + 1][d_max + 1],
  int result[d_max + 1][d_max + 1])
{
  identity_matrix(d, result);
  while (n) {
    if (n % 2 == 0) {
      matrix_multiply(d, m, matrix, matrix);
      n /= 2;
    }
    else {
      matrix_multiply(d, m, result, matrix);
      n--;
    }
  }
}

int main()
{
  while (true) {
    int d, n, m;
    scanf("%d %d %d", &d, &n, &m);
    if (!d)
      break;
    int f[d_max + 1], matrix[d_max + 1][d_max + 1];
    for (int i = 1; i <= d; i++) {
      scanf("%d", &matrix[1][i]);
      matrix[1][i] %= m;
    }
    for (int i = 1; i <= d; i++) {
      scanf("%d", &f[i]);
      f[i] %= m;
    }
    if (n <= d)
      printf("%d\n", f[n]);
    else {
      int result[d_max + 1][d_max + 1];
      for (int i = 2; i <= d; i++)
        for (int j = 1; j <= d; j++)
          matrix[i][j] = (i == j + 1) ? 1 : 0;
      matrix_power(d, n - d, m, matrix, result);
#ifdef DEBUG
      for (int i = 1; i <= d; i++)
        for (int j = 1; j <= d; j++)
          printf("%d%c", result[i][j], ((j < d) ? ' ' : '\n'));
#endif
      int r = 0;
      for (int i = 1; i <= d; i++) {
        r += result[1][i] * f[d - i + 1] % m;
        r %= m;
      }
      printf("%d\n", r);
    }
  }
  return 0;
}

Sunday, January 3, 2016

UVa 11472 - Beautiful Numbers

Accepted date: 2016-01-03
Run Time: 0.006
Ranking (as of 2016-01-03): 11 out of 453
Language: C++

/*
  UVa 11472 - Beautiful Numbers

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_11472_Beautiful_Numbers.cpp
*/

#include <cstdio>

const int N_max = 10, M_max = 100, mask_max = 1 << N_max, divisor = 1000000007;
int nrs[M_max + 1][N_max][mask_max];
  // [number of digits][lastdigit used][mask of used digits]

int main()
{
  for (int n = 1; n < N_max; n++)
    nrs[1][n][1 << n] = 1;
  for (int m = 2; m <= M_max; m++) {
    for (int i = 1; i < mask_max; i++)
      nrs[m][1][i | 1] = nrs[m - 1][0][i];
    for (int n = 1; n < N_max - 1; n++)
      for (int i = 1; i < mask_max; i++) {
        nrs[m][n - 1][i | 1 << (n - 1)] += nrs[m - 1][n][i];
        nrs[m][n - 1][i | 1 << (n - 1)] %= divisor;
        nrs[m][n + 1][i | 1 << (n + 1)] += nrs[m - 1][n][i];
        nrs[m][n + 1][i | 1 << (n + 1)] %= divisor;
      }
    for (int i = 1; i < mask_max; i++) {
      nrs[m][N_max - 2][i | 1 << (N_max - 2)] += nrs[m - 1][N_max - 1][i];
      nrs[m][N_max - 2][i | 1 << (N_max - 2)] %= divisor;
    }
  }

  int T;
  scanf("%d", &T);
  while (T--) {
    int N, M;
    scanf("%d %d", &N, &M);
    int mask = 1 << N, nr = 0;
    for (int m = 2; m <= M; m++)
      for (int n = 0; n < N; n++) {
        nr += nrs[m][n][mask - 1];
        nr %= divisor;
      }
    printf("%d\n", nr);
  }
  return 0;
}