SHOW:
|
|
- or go back to the newest paste.
| 1 | #include <iostream> | |
| 2 | #include <vector> | |
| 3 | #include <string> | |
| 4 | ||
| 5 | using namespace std; | |
| 6 | ||
| 7 | const int max_a = 100; | |
| 8 | const double epsilon = 1e-12; | |
| 9 | ||
| 10 | enum RESULT { LESS, GREATER, TOP_LESS, TOP_GREATER, TOP_EQUAL };
| |
| 11 | ||
| 12 | bool is_prime(int n) {
| |
| 13 | for (int i = 2; i * i <= n; i++) | |
| 14 | if (n % i == 0) | |
| 15 | return false; | |
| 16 | return true; | |
| 17 | } | |
| 18 | ||
| 19 | // decomposes n into prime factors | |
| 20 | vector <int> factor(int n) {
| |
| 21 | vector <int> result; | |
| 22 | for (int k = 2; k <= max_a; k++) | |
| 23 | if (is_prime(k)) {
| |
| 24 | int count = 0; | |
| 25 | while (n % k == 0) {
| |
| 26 | n /= k; | |
| 27 | count++; | |
| 28 | } | |
| 29 | result.push_back(count); | |
| 30 | } | |
| 31 | return result; | |
| 32 | } | |
| 33 | ||
| 34 | // returns the value of tower a | |
| 35 | double evaluate_double(const vector <int> &a) {
| |
| 36 | double result = 1.0; | |
| 37 | // check for overflow is necessary!!! | |
| 38 | for (int i = a.size() - 1; i >= 0; i--) | |
| 39 | result = pow(a[i], result); | |
| 40 | return result; | |
| 41 | } | |
| 42 | ||
| 43 | // returns the value of tower a | |
| 44 | int evaluate_int(const vector <int> &a) {
| |
| 45 | int result = 1; | |
| 46 | // check for overflow is necessary!!! | |
| 47 | for (int i = a.size() - 1; i >= 0; i--) {
| |
| 48 | int new_result = 1; | |
| 49 | for (int j = 0; j < result; j++) | |
| 50 | new_result *= a[i]; | |
| 51 | result = new_result; | |
| 52 | } | |
| 53 | return result; | |
| 54 | } | |
| 55 | ||
| 56 | // returns the logarithm of tower a | |
| 57 | double evaluate_log(const vector <int> &a) {
| |
| 58 | if (a.size() == 0) | |
| 59 | return 0.0; | |
| 60 | else {
| |
| 61 | vector <int> new_a(++a.begin(), a.end()); | |
| 62 | return log((double)a[0]) * evaluate_double(new_a); | |
| 63 | } | |
| 64 | } | |
| 65 | ||
| 66 | int gcd(int a, int b) {
| |
| 67 | return b == 0 ? a : gcd(b, a % b); | |
| 68 | } | |
| 69 | ||
| 70 | // compares real number to a tower | |
| 71 | // x >= 1.0 | |
| 72 | bool is_less(double x, const vector <int> &a) {
| |
| 73 | for (int i = 0; i < a.size(); i++) {
| |
| 74 | x = log(x) / log((double)a[i]); | |
| 75 | if (x < 1) | |
| 76 | return true; | |
| 77 | } | |
| 78 | return false; | |
| 79 | } | |
| 80 | ||
| 81 | // returns true if a * p == b * q | |
| 82 | // a, b - towers | |
| 83 | // p, q >= 1 | |
| 84 | bool is_equal(const vector <int> &a, int p, const vector <int> &b, int q) {
| |
| 85 | if (a.size() == 0 && b.size() == 0) | |
| 86 | return p == q; | |
| 87 | else if (a.size() == 0) | |
| 88 | // a == 1 | |
| 89 | // p >= b && p == b * q | |
| 90 | // multiply p by 2 to avoid rounding problems | |
| 91 | return !is_less(2 * p, b) && p == evaluate_int(b) * q; | |
| 92 | else if (b.size() == 0) | |
| 93 | // b == 1 | |
| 94 | // q >= a && q == a * p | |
| 95 | // multiply q by 2 to avoid rounding problems | |
| 96 | return !is_less(2 * q, a) && q == evaluate_int(a) * p; | |
| 97 | vector <int> f_p = factor(p); | |
| 98 | vector <int> f_a = factor(a[0]); | |
| 99 | vector <int> f_q = factor(q); | |
| 100 | vector <int> f_b = factor(b[0]); | |
| 101 | vector <int> new_a(a.begin() + 1, a.end()); | |
| 102 | vector <int> new_b(b.begin() + 1, b.end()); | |
| 103 | int c = -1, d = -1; | |
| 104 | // check each prime factor | |
| 105 | for (int i = 0; i < f_p.size(); i++) {
| |
| 106 | if (f_p[i] != f_q[i]) {
| |
| 107 | int value_a = evaluate_int(new_a); | |
| 108 | int value_b = evaluate_int(new_b); | |
| 109 | // check for overflow!!! | |
| 110 | if (f_a[i] * value_a + f_p[i] != f_b[i] * value_b + f_q[i]) | |
| 111 | return false; | |
| 112 | } | |
| 113 | else if ((f_a[i] == 0) != (f_b[i] == 0)) | |
| 114 | return false; | |
| 115 | else if (f_a[i] != 0 && f_b[i] != 0) {
| |
| 116 | // f_a[i] >= 1, f_b[i] >= 1 | |
| 117 | int g = gcd(f_a[i], f_b[i]); | |
| 118 | int new_c = f_a[i] / g; | |
| 119 | int new_d = f_b[i] / g; | |
| 120 | if (c == -1 && d == -1) {
| |
| 121 | c = new_c; | |
| 122 | d = new_d; | |
| 123 | } | |
| 124 | else if (c != new_c || d != new_d) | |
| 125 | return false; | |
| 126 | } | |
| 127 | } | |
| 128 | if (c == -1 && d == -1) | |
| 129 | return true; | |
| 130 | else | |
| 131 | return is_equal(new_a, c, new_b, d); | |
| 132 | } | |
| 133 | ||
| 134 | // a.size(), b.size() >= 1 | |
| 135 | // returns LESS if the whole tower a is less than b | |
| 136 | // returns GREATER if the whole tower a is greater than b | |
| 137 | // returns TOP_LESS if the top part of tower a is less than the top part of tower b | |
| 138 | // returns TOP_GREATER if the top part of tower a is greater than the top part of tower b | |
| 139 | // returns TOP_EQUAL if the top part of tower a equals the top part of tower b | |
| 140 | RESULT solve(const vector <int> &a, const vector <int> &b) {
| |
| 141 | double x = a[0]; | |
| 142 | double y = b[0]; | |
| 143 | vector <int> new_a(a.begin() + 1, a.end()); | |
| 144 | vector <int> new_b(b.begin() + 1, b.end()); | |
| 145 | // consider the case where new_a == new_b | |
| 146 | if (is_equal(new_a, 1, new_b, 1)) {
| |
| 147 | double d = log(log(x)) - log(log(y)); | |
| 148 | if (x == y) | |
| 149 | return TOP_EQUAL; | |
| 150 | else if (d > epsilon && is_less(log(10.0) / (d * log(y)), new_a)) | |
| 151 | return GREATER; | |
| 152 | else if (d < -epsilon && is_less(log(10.0) / (-d * log(x)), new_a)) | |
| 153 | return LESS; | |
| 154 | else if (d > 0) | |
| 155 | return TOP_GREATER; | |
| 156 | else | |
| 157 | return TOP_LESS; | |
| 158 | } | |
| 159 | else {
| |
| 160 | double log_x_a = evaluate_log(new_a) + log(log(x)); | |
| 161 | double log_y_b = evaluate_log(new_b) + log(log(y)); | |
| 162 | double d = log_x_a - log_y_b; | |
| 163 | if (d > epsilon && log_y_b > log(log(10.0)) - log(d)) | |
| 164 | return GREATER; | |
| 165 | else if (d < -epsilon && log_x_a > log(log(10.0)) - log(-d)) | |
| 166 | return LESS; | |
| 167 | else if (is_equal(a, 1, b, 1)) | |
| 168 | return TOP_EQUAL; | |
| 169 | else if (d > 0) | |
| 170 | return TOP_GREATER; | |
| 171 | else | |
| 172 | return TOP_LESS; | |
| 173 | } | |
| 174 | } | |
| 175 | ||
| 176 | vector <int> read_tower(istream &in) {
| |
| 177 | int n; | |
| 178 | in >> n; | |
| 179 | vector <int> result(n); | |
| 180 | for (int i = 0; i < n; i++) | |
| 181 | in >> result[i]; | |
| 182 | // normalize tower (remove all ones) | |
| 183 | for (int i = 0; i < result.size(); i++) | |
| 184 | if (result[i] == 1) {
| |
| 185 | result.erase(result.begin() + i, result.end()); | |
| 186 | break; | |
| 187 | } | |
| 188 | return result; | |
| 189 | } | |
| 190 | ||
| 191 | int main() {
| |
| 192 | vector <int> a = read_tower(cin); | |
| 193 | vector <int> b = read_tower(cin); | |
| 194 | // each element of towers is >= 2 and <= max_a | |
| 195 | RESULT ans; | |
| 196 | if (a.size() >= b.size() + 3) | |
| 197 | ans = GREATER; | |
| 198 | else if (b.size() >= a.size() + 3) | |
| 199 | ans = LESS; | |
| 200 | else if (a.size() == 0 && b.size() == 0) | |
| 201 | ans = TOP_EQUAL; | |
| 202 | else if (a.size() == 0 && b.size() != 0) | |
| 203 | ans = LESS; | |
| 204 | else if (b.size() == 0 && a.size() != 0) | |
| 205 | ans = GREATER; | |
| 206 | else {
| |
| 207 | for (int i = min(a.size() - 1, b.size() - 1); i >= 0; i--) {
| |
| 208 | vector <int> new_a(a.begin() + i, a.end()); | |
| 209 | vector <int> new_b(b.begin() + i, b.end()); | |
| 210 | ans = solve(new_a, new_b); | |
| 211 | if (ans == LESS || ans == GREATER) | |
| 212 | break; | |
| 213 | } | |
| 214 | } | |
| 215 | if (ans == LESS || ans == TOP_LESS) | |
| 216 | cout << "Less" << endl; | |
| 217 | else if (ans == GREATER || ans == TOP_GREATER) | |
| 218 | cout << "Greater" << endl; | |
| 219 | else | |
| 220 | cout << "Equal" << endl; | |
| 221 | return 0; | |
| 222 | } | |
| 223 | ||
| 224 | // Input format: | |
| 225 | // n | |
| 226 | // a1 a2 ... an | |
| 227 | // m | |
| 228 | // b1 b2 ... bm |