View difference between Paste ID: UkJxZc8B and 31ymMpNn
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