#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;
int MOD = 1000000007;
struct Tree {
int left;
int right;
};
void add_zero(std::vector<std::pair<int, int>> &counts) {
std::pair<int, int> p;
p.first = 0;
p.second = 1;
counts.push_back(p);
}
std::vector<std::vector<std::pair<int, int>>> count_endings(std::vector<Tree> &tree,
std::vector<std::pair<int, int>>& left_leaf, std::vector<std::pair<int, int>>& right_leaf) {
std::vector<std::pair<int, int>> base;
std::vector<std::vector<std::pair<int, int>>> mem(tree.size(), base);
for (int i=tree.size()-1; i >= 0; i--) {
Tree t = tree[i];
std::vector<std::pair<int, int>> &counts = mem.at(i);
std::vector<std::pair<int, int>> l_mem;
if (t.left != -1) {
l_mem = mem.at(t.left);
} else {
l_mem = left_leaf;
}
std::vector<std::pair<int, int>> r_mem;
if (t.right != -1) {
r_mem = mem.at(t.right);
} else {
r_mem = right_leaf;
}
int li = 0;
int ri = 0;
// std::cout << l_mem.size() << "\n";
// std::cout << r_mem.size() << "\n";
while (li < l_mem.size() || ri < r_mem.size()) {
std::pair<int, int> l_pair;
std::pair<int, int> r_pair;
std::pair<int, int> p;
if (li < l_mem.size()) {
l_pair = l_mem.at(li);
}
if (ri < r_mem.size()) {
r_pair = r_mem.at(ri);
}
if (ri >= r_mem.size() || l_pair.first < r_pair.first - 2) {
//std::cout << "case left\n";
p = l_pair;
p.first += 1;
li++;
} else if (li >= l_mem.size() || l_pair.first > r_pair.first - 2) {
//std::cout << "case right\n";
p = r_pair;
p.first -= 1;
if (p.first == 0) {
p.second = 0;
}
ri++;
} else {
//std::cout << "case both\n";
p = l_pair;
p.first += 1;
if (p.first != 0) {
p.second += r_pair.second;
}
li++;
ri++;
}
if (p.first == 0) {
p.second++;
}
//std::cout << "kel " << p.first << " " << p.second << "\n";
if (p.first > 0 && counts.size() == 0) {
add_zero(counts);
}
p.second %= MOD;
counts.push_back(p);
}
if (counts.size() == 0 || counts.at(counts.size()-1).first < 0) {
add_zero(counts);
}
// std::cout << i << " counts\n";
// for (auto pair : counts) {
// std::cout << pair.first << " - " << pair.second << "\n";
// }
}
// std::cout << "Root counts\n";
// for (auto pair : mem.at(0)) {
// std::cout << pair.first << " - " << pair.second << '\n';
// }
return mem;
}
std::vector<Tree> build_tree(std::string &s) {
std::vector<Tree> trees;
std::vector<int> wo_left;
std::vector<int> wo_right;
Tree root;
root.left = -1;
root.right = -1;
trees.push_back(root);
wo_left.push_back(0);
wo_right.push_back(0);
for (int i=0; i<s.length(); i++) {
Tree t;
t.left = -1;
t.right = -1;
trees.push_back(t);
if (s[i] == 'L') {
for (int v : wo_left) {
trees[v].left = i+1;
}
wo_left.clear();
} else {
for (int v : wo_right) {
trees[v].right = i+1;
}
wo_right.clear();
}
wo_left.push_back(i+1);
wo_right.push_back(i+1);
}
// for (Tree t : trees) {
// std::cout << t.left << " " << t.right << '\n';
// }
return trees;
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
int n;
std::cin >> n;
std::vector<std::vector<Tree>> trees;
std::vector<std::vector<std::pair<int, int>>> left_leafs;
std::vector<std::vector<std::pair<int, int>>> right_leafs;
std::vector<std::string> data;
for (int i=0; i<n; i++) {
std::string s;
std::cin >> s;
//data.push_back(data);
std::vector<Tree> t = build_tree(s);
trees.push_back(build_tree(s));
std::vector<std::pair<int, int>> leaf_count;
std::vector<std::vector<std::pair<int, int>>> counts = count_endings(t, leaf_count, leaf_count);
std::vector<std::pair<int, int>> left_leaf, right_leaf;
if (t.at(0).left != -1) {
left_leaf = counts.at(t.at(0).left);
}
if (t.at(0).right != -1) {
right_leaf = counts.at(t.at(0).right);
}
left_leafs.push_back(left_leaf);
right_leafs.push_back(right_leaf);
}
for (int i=0; i<n; i++) {
std::vector<Tree>& t = trees.at(i);
for (int j=0; j<n; j++) {
std::vector<std::pair<int, int>>& left_leaf = left_leafs.at(j);
std::vector<std::pair<int, int>>& right_leaf = right_leafs.at(j);
std::vector<std::vector<std::pair<int, int>>> counts = count_endings(t, left_leaf, right_leaf);
for (std::pair<int, int> p : counts.at(0)) {
if (p.first == 0) {
p.second += MOD-1;
p.second %= MOD;
std::cout << p.second << " ";
break;
}
}
}
std::cout << "\n";
}
}
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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | #include <iostream> #include <map> #include <vector> #include <algorithm> #include <utility> using namespace std; int MOD = 1000000007; struct Tree { int left; int right; }; void add_zero(std::vector<std::pair<int, int>> &counts) { std::pair<int, int> p; p.first = 0; p.second = 1; counts.push_back(p); } std::vector<std::vector<std::pair<int, int>>> count_endings(std::vector<Tree> &tree, std::vector<std::pair<int, int>>& left_leaf, std::vector<std::pair<int, int>>& right_leaf) { std::vector<std::pair<int, int>> base; std::vector<std::vector<std::pair<int, int>>> mem(tree.size(), base); for (int i=tree.size()-1; i >= 0; i--) { Tree t = tree[i]; std::vector<std::pair<int, int>> &counts = mem.at(i); std::vector<std::pair<int, int>> l_mem; if (t.left != -1) { l_mem = mem.at(t.left); } else { l_mem = left_leaf; } std::vector<std::pair<int, int>> r_mem; if (t.right != -1) { r_mem = mem.at(t.right); } else { r_mem = right_leaf; } int li = 0; int ri = 0; // std::cout << l_mem.size() << "\n"; // std::cout << r_mem.size() << "\n"; while (li < l_mem.size() || ri < r_mem.size()) { std::pair<int, int> l_pair; std::pair<int, int> r_pair; std::pair<int, int> p; if (li < l_mem.size()) { l_pair = l_mem.at(li); } if (ri < r_mem.size()) { r_pair = r_mem.at(ri); } if (ri >= r_mem.size() || l_pair.first < r_pair.first - 2) { //std::cout << "case left\n"; p = l_pair; p.first += 1; li++; } else if (li >= l_mem.size() || l_pair.first > r_pair.first - 2) { //std::cout << "case right\n"; p = r_pair; p.first -= 1; if (p.first == 0) { p.second = 0; } ri++; } else { //std::cout << "case both\n"; p = l_pair; p.first += 1; if (p.first != 0) { p.second += r_pair.second; } li++; ri++; } if (p.first == 0) { p.second++; } //std::cout << "kel " << p.first << " " << p.second << "\n"; if (p.first > 0 && counts.size() == 0) { add_zero(counts); } p.second %= MOD; counts.push_back(p); } if (counts.size() == 0 || counts.at(counts.size()-1).first < 0) { add_zero(counts); } // std::cout << i << " counts\n"; // for (auto pair : counts) { // std::cout << pair.first << " - " << pair.second << "\n"; // } } // std::cout << "Root counts\n"; // for (auto pair : mem.at(0)) { // std::cout << pair.first << " - " << pair.second << '\n'; // } return mem; } std::vector<Tree> build_tree(std::string &s) { std::vector<Tree> trees; std::vector<int> wo_left; std::vector<int> wo_right; Tree root; root.left = -1; root.right = -1; trees.push_back(root); wo_left.push_back(0); wo_right.push_back(0); for (int i=0; i<s.length(); i++) { Tree t; t.left = -1; t.right = -1; trees.push_back(t); if (s[i] == 'L') { for (int v : wo_left) { trees[v].left = i+1; } wo_left.clear(); } else { for (int v : wo_right) { trees[v].right = i+1; } wo_right.clear(); } wo_left.push_back(i+1); wo_right.push_back(i+1); } // for (Tree t : trees) { // std::cout << t.left << " " << t.right << '\n'; // } return trees; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int n; std::cin >> n; std::vector<std::vector<Tree>> trees; std::vector<std::vector<std::pair<int, int>>> left_leafs; std::vector<std::vector<std::pair<int, int>>> right_leafs; std::vector<std::string> data; for (int i=0; i<n; i++) { std::string s; std::cin >> s; //data.push_back(data); std::vector<Tree> t = build_tree(s); trees.push_back(build_tree(s)); std::vector<std::pair<int, int>> leaf_count; std::vector<std::vector<std::pair<int, int>>> counts = count_endings(t, leaf_count, leaf_count); std::vector<std::pair<int, int>> left_leaf, right_leaf; if (t.at(0).left != -1) { left_leaf = counts.at(t.at(0).left); } if (t.at(0).right != -1) { right_leaf = counts.at(t.at(0).right); } left_leafs.push_back(left_leaf); right_leafs.push_back(right_leaf); } for (int i=0; i<n; i++) { std::vector<Tree>& t = trees.at(i); for (int j=0; j<n; j++) { std::vector<std::pair<int, int>>& left_leaf = left_leafs.at(j); std::vector<std::pair<int, int>>& right_leaf = right_leafs.at(j); std::vector<std::vector<std::pair<int, int>>> counts = count_endings(t, left_leaf, right_leaf); for (std::pair<int, int> p : counts.at(0)) { if (p.first == 0) { p.second += MOD-1; p.second %= MOD; std::cout << p.second << " "; break; } } } std::cout << "\n"; } } |
English