#include <algorithm> #include <cstdint> #include <deque> #include <ios> #include <iostream> #include <iterator> #include <limits> #include <string> #include <tuple> #include <unordered_map> #include <unordered_set> #include <vector> #include <bits/stdc++.h> using namespace std; // Debugging functions from https://codeforces.com/blog/entry/68809 (not affecting the solution in any way). void __print(int x) {cerr << x;} void __print(long x) {cerr << x;} void __print(long long x) {cerr << x;} void __print(unsigned x) {cerr << x;} void __print(unsigned long x) {cerr << x;} void __print(unsigned long long x) {cerr << x;} void __print(float x) {cerr << x;} void __print(double x) {cerr << x;} void __print(long double x) {cerr << x;} void __print(char x) {cerr << '\'' << x << '\'';} void __print(const char *x) {cerr << '\"' << x << '\"';} void __print(const string &x) {cerr << '\"' << x << '\"';} void __print(bool x) {cerr << (x ? "true" : "false");} template<typename T, typename V> void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';} template<typename T> void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";} void _print() {cerr << "]\n";} template <typename T, typename... V> void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);} #define debug(x...) // cerr << "[" << #x << "] = ["; _print(x) void prelude() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); } constexpr int64_t MOD = 1'000'000'007; void inc(int64_t &to, int64_t what) { debug(to, "into"); debug(what, "what"); to = (to + what) % MOD; } int main() { prelude(); int n = 0; std::vector<std::vector<bool>> input; std::cin >> n; std::cin.ignore(); for (int i = 0; i < n; ++i) { std::string tmp; std::getline(std::cin, tmp); debug(tmp, "tmp"); input.push_back({}); input[i].resize(tmp.size()); for (int j = 0; j < tmp.size(); ++j) { input[i][j] = tmp[j] == 'P'; } } for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { std::vector<bool> concat; concat.reserve(input[i].size() + input[j].size()); std::copy(input[i].begin(), input[i].end(), std::back_inserter(concat)); std::copy(input[j].begin(), input[j].end(), std::back_inserter(concat)); std::vector<int64_t> outputs_count(concat.size() + 2, 0); outputs_count[0] = 1; for (bool x : concat) { debug(x, "processing"); int offset = x ? 1 : 0; int opposite = 1 - offset; int dir = x ? -1 : 1; // Different direction of iteration needed to prevent stomping of needed // values. if (x) { for (int over = 1; over <= concat.size() / 2; ++over) { debug(2 * over + offset, "from"); debug(2 * (over + dir) + 1, "to"); inc(outputs_count[2 * (over + dir) + 1], outputs_count[2 * over + offset]); debug(2 * (over + dir), "to"); inc(outputs_count[2 * (over + dir)], outputs_count[2 * over + offset]); outputs_count[2 * over + offset] = 0; } } else { for (int over = concat.size() / 2 - 1; over >= 0; --over) { debug(2 * over + offset, "from"); debug(2 * (over + dir) + 1, "to"); inc(outputs_count[2 * (over + dir) + 1], outputs_count[2 * over + offset]); debug(2 * (over + dir), "to"); inc(outputs_count[2 * (over + dir)], outputs_count[2 * over + offset]); outputs_count[2 * over + offset] = 0; } } debug(outputs_count, "counts"); } std::cout << outputs_count[1] << " "; } std::cout << "\n"; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #include <algorithm> #include <cstdint> #include <deque> #include <ios> #include <iostream> #include <iterator> #include <limits> #include <string> #include <tuple> #include <unordered_map> #include <unordered_set> #include <vector> #include <bits/stdc++.h> using namespace std; // Debugging functions from https://codeforces.com/blog/entry/68809 (not affecting the solution in any way). void __print(int x) {cerr << x;} void __print(long x) {cerr << x;} void __print(long long x) {cerr << x;} void __print(unsigned x) {cerr << x;} void __print(unsigned long x) {cerr << x;} void __print(unsigned long long x) {cerr << x;} void __print(float x) {cerr << x;} void __print(double x) {cerr << x;} void __print(long double x) {cerr << x;} void __print(char x) {cerr << '\'' << x << '\'';} void __print(const char *x) {cerr << '\"' << x << '\"';} void __print(const string &x) {cerr << '\"' << x << '\"';} void __print(bool x) {cerr << (x ? "true" : "false");} template<typename T, typename V> void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';} template<typename T> void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";} void _print() {cerr << "]\n";} template <typename T, typename... V> void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);} #define debug(x...) // cerr << "[" << #x << "] = ["; _print(x) void prelude() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); } constexpr int64_t MOD = 1'000'000'007; void inc(int64_t &to, int64_t what) { debug(to, "into"); debug(what, "what"); to = (to + what) % MOD; } int main() { prelude(); int n = 0; std::vector<std::vector<bool>> input; std::cin >> n; std::cin.ignore(); for (int i = 0; i < n; ++i) { std::string tmp; std::getline(std::cin, tmp); debug(tmp, "tmp"); input.push_back({}); input[i].resize(tmp.size()); for (int j = 0; j < tmp.size(); ++j) { input[i][j] = tmp[j] == 'P'; } } for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { std::vector<bool> concat; concat.reserve(input[i].size() + input[j].size()); std::copy(input[i].begin(), input[i].end(), std::back_inserter(concat)); std::copy(input[j].begin(), input[j].end(), std::back_inserter(concat)); std::vector<int64_t> outputs_count(concat.size() + 2, 0); outputs_count[0] = 1; for (bool x : concat) { debug(x, "processing"); int offset = x ? 1 : 0; int opposite = 1 - offset; int dir = x ? -1 : 1; // Different direction of iteration needed to prevent stomping of needed // values. if (x) { for (int over = 1; over <= concat.size() / 2; ++over) { debug(2 * over + offset, "from"); debug(2 * (over + dir) + 1, "to"); inc(outputs_count[2 * (over + dir) + 1], outputs_count[2 * over + offset]); debug(2 * (over + dir), "to"); inc(outputs_count[2 * (over + dir)], outputs_count[2 * over + offset]); outputs_count[2 * over + offset] = 0; } } else { for (int over = concat.size() / 2 - 1; over >= 0; --over) { debug(2 * over + offset, "from"); debug(2 * (over + dir) + 1, "to"); inc(outputs_count[2 * (over + dir) + 1], outputs_count[2 * over + offset]); debug(2 * (over + dir), "to"); inc(outputs_count[2 * (over + dir)], outputs_count[2 * over + offset]); outputs_count[2 * over + offset] = 0; } } debug(outputs_count, "counts"); } std::cout << outputs_count[1] << " "; } std::cout << "\n"; } return 0; } |