From 218a2fb56accaba5e070714fd71213059a834814 Mon Sep 17 00:00:00 2001 From: e2hang <2099307493@qq.com> Date: Fri, 24 Oct 2025 09:52:24 +0800 Subject: [PATCH] Hm3 --- Exercise/Homework3/Q1.cpp | 214 ++++++++++++++++++++++ Exercise/Homework3/Q1.rs | 0 Exercise/Homework3/Q1双栈做法.cpp | 191 +++++++++++++++++++ Exercise/Homework3/Q1过了的版本.cpp | 194 ++++++++++++++++++++ Exercise/Homework3/Q2.rs | 34 ++++ Exercise/Homework3/Q3.rs | 79 ++++++++ Exercise/Homework3/grok的表达式树模板.cpp | 153 ++++++++++++++++ Exercise/Homework3/表达式树模板.cpp | 146 +++++++++++++++ 8 files changed, 1011 insertions(+) create mode 100644 Exercise/Homework3/Q1.cpp create mode 100644 Exercise/Homework3/Q1.rs create mode 100644 Exercise/Homework3/Q1双栈做法.cpp create mode 100644 Exercise/Homework3/Q1过了的版本.cpp create mode 100644 Exercise/Homework3/Q2.rs create mode 100644 Exercise/Homework3/Q3.rs create mode 100644 Exercise/Homework3/grok的表达式树模板.cpp create mode 100644 Exercise/Homework3/表达式树模板.cpp diff --git a/Exercise/Homework3/Q1.cpp b/Exercise/Homework3/Q1.cpp new file mode 100644 index 0000000..d86a6f8 --- /dev/null +++ b/Exercise/Homework3/Q1.cpp @@ -0,0 +1,214 @@ +#include +#include +using namespace std; +//뷨ʽм㣨 +//ȻҲջһһ֣ң + +// +long long fastpow(long long d, long long u){ + //d^uÿ + long long result = 1, base = d, b = u; + while(b > 0){ + if(b & 1) result *= base; + base *= base; + b >>= 1; + } + return result; +} +int level(char c){ + switch(c){ + case '+': + case '-': { + return 1; + break; + } + case '*': + case '/': { + return 2; + break; + } + case '^': { + return 3; + break; + } + default: { + return 0; + break; + } + } +} + +int findexp(const string& s, int l, int r) { + int pos = -1; + int min_level = 114514; + int js = 0; + for (int i = r; i >= l; i--) { + if (s[i] == ')') js--; + else if (s[i] == '(') js++; + + if (js == 0 && level(s[i])) { + // ҽϵ^ʹ<<= + if ((s[i] == '^' && level(s[i]) < min_level) || + (s[i] != '^' && level(s[i]) <= min_level)) { + min_level = level(s[i]); + pos = i; + } + } + } + return pos; +} + +long long toNum(const string& s, int l, int r) { + long long tmp = 0; + + // ո + while (l <= r && s[l] == ' ') l++; + while (l <= r && s[r] == ' ') r--; + + if (l > r) return 0; + + // Ҵ + for (int i = l; i <= r; i++) { + if (isdigit(s[i])) { + tmp = tmp * 10 + (s[i] - '0'); + } else { + return 0; // Ƿַ + } + } + + return tmp; +} +/* +ŵİ汾 +long long toNum(const string& s, int l, int r){ + long long tmp = 0; + bool neg = false; + if (s[l] == '-') { neg = true; l++; } + for(int i = l; i <= r; i++){ + if(isdigit(s[i])) tmp = tmp * 10 + (s[i] - '0'); + } + return neg ? -tmp : tmp; +} +*/ + +struct Node{ + char sign; + long long num; + Node* left; + Node* right; + + Node(): sign('?'), num(-1), left(nullptr), right(nullptr) {} + Node(char s): sign(s), num(-1), left(nullptr), right(nullptr) {} + Node(long long n): sign('?'), num(n), left(nullptr), right(nullptr) {} +}; + +class Expression{ +public: + string exp; + Node* root; + long long result; + bool isValid; + + Expression(const string& s): exp(s), root(nullptr), result(-1), isValid(true) {} + + void inorder(Node* r){ + if(!r) return; + inorder(r->left); + if (r->sign == '?') cout << r->num; + else cout << r->sign; + inorder(r->right); + } + + Node* build(const string& s, int l, int r){ + //[l, r] + //ո + while(l <= r && s[l] == ' ') l++; + while(l <= r && s[r] == ' ') r--; + if(l > r) return nullptr; + //ⲿ + if(s[l] == '(' && s[r] == ')'){ + bool hasQuote = true; + int js = 0; + for(int i = l; i <= r; i++){ + if(s[i] == '(') js++; + else if(s[i] == ')') js--; + + if(js == 0 && i != r){ + hasQuote = false; + break; + } + } + if (hasQuote) return build(s, l + 1, r - 1); + } + + int pos = findexp(s, l, r); + // + if(pos == -1) { + long long x = toNum(s, l, r); + //cout << "*" << r << endl; Ϊʲô0 + return new Node(x); + //·ڵ + } + Node* tmp = new Node(s[pos]); + tmp->left = build(s, l, pos - 1); + tmp->right = build(s, pos + 1, r); + return tmp; + } + + long long calc(Node* r, bool& isValid){ + if(!r) return 0; + // + if(r->sign == '?') return r->num; + + // + long long left = calc(r->left, isValid); + long long right = calc(r->right, isValid); + if(r->num == -1){ + char c = r->sign; + switch(c){ + case '+': return left + right; + case '-': return left - right; + case '*': return left * right; + case '/': { + if(right == 0) { + isValid = false; + return 0; + } + else return left / right; + } + case '^': { + if(left == 0 && right == 0) { isValid = false; return 0; } + return fastpow(left, right); + break; + } + default: return 0; + } + } + } + void print(){ + inorder(root); + } +}; + + + +int main(){ + /* + string s; + getline(cin, s); + Expression tree(s); + tree.root = tree.build(s, 0, s.length() - 1); + //tree.print(); + cout << tree.calc(tree.root, tree.isValid) << endl; + //if(!tree.isValid && result != -1) cout << result < +using namespace std; + +//--------------------------------------------- +// +//--------------------------------------------- +const long long INF = 1LL << 31; // ĿҪΧ [-2^31, 2^31) + +//--------------------------------------------- +// ȼ +//--------------------------------------------- +// һȼȼֵԽȼԽߣ +int level(char op) { + switch (op) { + case '+': case '-': return 1; // Ӽ + case '*': case '/': return 2; // ˳е + case '^': return 3; // + default: return 0; // + } +} + +//--------------------------------------------- +// жǷҽϵ +//--------------------------------------------- +// ֻ㣨^ҽϣa^b^c ȼ a^(b^c) +bool rightAssoc(char op) { + return op == '^'; +} + +//--------------------------------------------- +// ȫݺ⣩ +//--------------------------------------------- +// ϵͳ powԼд +// ͬʱҪǷ񳬹ĿҪΧ int32 +long long fastpow(long long a, long long b, bool &valid) { + long long res = 1; + while (b > 0) { + // ǰλ1Ҫһ + if (b & 1) { + // жǷ + if (a != 0 && llabs(res) > (INF - 1) / llabs(a)) { + valid = false; + return 0; + } + res *= a; + } + // ׼ƽ + b >>= 1; + if (b) { // ûжһƽǷȫ + if (llabs(a) > (INF - 1) / llabs(a)) { + valid = false; + return 0; + } + a *= a; + } + } + return res; +} + +//--------------------------------------------- +// ִһ㣺ջȡͲ +//--------------------------------------------- +bool apply(stack &num, stack &op) { + if (num.size() < 2 || op.empty()) return false; // + long long b = num.top(); num.pop(); // ע˳Ҳ + long long a = num.top(); num.pop(); // + char c = op.top(); op.pop(); // + + long long res = 0; + switch (c) { + case '+': res = a + b; break; + case '-': res = a - b; break; + case '*': res = a * b; break; + case '/': + if (b == 0) return false; // 㱨 + res = a / b; // Զβ + break; + case '^': { + if (b < 0) return false; // Ŀָ֤Ǹ + bool valid = true; + res = fastpow(a, b, valid); + if (!valid) return false; // + break; + } + default: + return false; // Ƿ + } + + // Χ + if (res >= INF || res < -INF) return false; + + num.push(res); + return true; +} + +//--------------------------------------------- +// 㺯һбʽ +//--------------------------------------------- +string calcExpr(const string &s) { + stack num; // ջ + stack op; // ջ + int n = s.size(); + + for (int i = 0; i < n; ) { + if (isspace(s[i])) { // ո + i++; + continue; + } + + //------------------------------------- + // ֶ֣֧λ + //------------------------------------- + if (isdigit(s[i])) { + long long val = 0; + while (i < n && isdigit(s[i])) { + val = val * 10 + (s[i] - '0'); + if (val >= INF) return "INVALID"; // Χ + i++; + } + num.push(val); + } + + //------------------------------------- + // + //------------------------------------- + else if (s[i] == '(') { + op.push('('); + i++; + } + + //------------------------------------- + // ţҪ㵽һ'('Ϊֹ + //------------------------------------- + else if (s[i] == ')') { + while (!op.empty() && op.top() != '(') { + if (!apply(num, op)) return "INVALID"; + } + if (op.empty()) return "INVALID"; // Ųƥ + op.pop(); // '(' + i++; + } + + //------------------------------------- + // + //------------------------------------- + else { + char now = s[i]; + if (level(now) == 0) return "INVALID"; // Ƿַ + + // ջȼ߻ͬҲҽϣȼ + while (!op.empty() && op.top() != '(' && + (level(op.top()) > level(now) || + (level(op.top()) == level(now) && !rightAssoc(now)))) { + if (!apply(num, op)) return "INVALID"; + } + op.push(now); + i++; + } + } + + //------------------------------------- + // ջʣ + //------------------------------------- + while (!op.empty()) { + if (!apply(num, op)) return "INVALID"; + } + + //------------------------------------- + // ջֹһ˵ʽ + //------------------------------------- + if (num.size() != 1) return "INVALID"; + + // ս + return to_string(num.top()); +} + +//--------------------------------------------- +// 룬ÿһʽ +//--------------------------------------------- +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + + string s; + while (getline(cin, s)) { + string ans = calcExpr(s); + cout << ans << "\n"; + } + return 0; +} + diff --git a/Exercise/Homework3/Q1过了的版本.cpp b/Exercise/Homework3/Q1过了的版本.cpp new file mode 100644 index 0000000..54539a7 --- /dev/null +++ b/Exercise/Homework3/Q1过了的版本.cpp @@ -0,0 +1,194 @@ +#include +#include +using namespace std; + +// +long long fastpow(long long d, long long u){ + //d^uÿ + long long result = 1, base = d, b = u; + while(b > 0){ + if(b & 1) result *= base; + base *= base; + b >>= 1; + } + return result; +} + +int level(char c){ + switch(c){ + case '+': + case '-': { + return 1; + break; + } + case '*': + case '/': { + return 2; + break; + } + case '^': { + return 3; + break; + } + default: { + return 0; + break; + } + } +} + +int findexp(const string& s, int l, int r) { + int pos = -1; + int min_level = 114514; + int js = 0; + for (int i = r; i >= l; i--) { + if (s[i] == ')') js--; + else if (s[i] == '(') js++; + + if (js == 0 && level(s[i])) { + int lev = level(s[i]); + if (lev < min_level || (lev == min_level && s[i] == '^')) { + min_level = lev; + pos = i; + } + } + } + return pos; +} + +long long toNum(const string& s, int l, int r) { + long long tmp = 0; + + // ո + while (l <= r && s[l] == ' ') l++; + while (l <= r && s[r] == ' ') r--; + + if (l > r) return 0; + + // Ҵ + for (int i = l; i <= r; i++) { + if (isdigit(s[i])) { + tmp = tmp * 10 + (s[i] - '0'); + } else { + return 0; // Ƿַ + } + } + + return tmp; +} + +struct Node{ + char sign; + long long num; + Node* left; + Node* right; + + Node(): sign('?'), num(-1), left(nullptr), right(nullptr) {} + Node(char s): sign(s), num(-1), left(nullptr), right(nullptr) {} + Node(long long n): sign('?'), num(n), left(nullptr), right(nullptr) {} +}; + +class Expression{ +public: + string exp; + Node* root; + long long result; + bool isValid; + + Expression(const string& s): exp(s), root(nullptr), result(-1), isValid(true) {} + + void inorder(Node* r){ + if(!r) return; + inorder(r->left); + if (r->sign == '?') cout << r->num; + else cout << r->sign; + inorder(r->right); + } + + Node* build(const string& s, int l, int r){ + //[l, r] + //ո + while(l <= r && s[l] == ' ') l++; + while(l <= r && s[r] == ' ') r--; + if(l > r) return nullptr; + //ⲿ + if(s[l] == '(' && s[r] == ')'){ + bool hasQuote = true; + int js = 0; + for(int i = l; i <= r; i++){ + if(s[i] == '(') js++; + else if(s[i] == ')') js--; + + if(js == 0 && i != r){ + hasQuote = false; + break; + } + } + if (hasQuote) return build(s, l + 1, r - 1); + } + + int pos = findexp(s, l, r); + // + if(pos == -1) { + long long x = toNum(s, l, r); + return new Node(x); + } + Node* tmp = new Node(s[pos]); + tmp->left = build(s, l, pos - 1); + tmp->right = build(s, pos + 1, r); + return tmp; + } + + long long calc(Node* r, bool& isValid){ + if(!r) return 0; + // + if(r->sign == '?') return r->num; + + // + long long left = calc(r->left, isValid); + long long right = calc(r->right, isValid); + if(r->num == -1){ + char c = r->sign; + switch(c){ + case '+': return left + right; + case '-': return left - right; + case '*': return left * right; + case '/': { + if(right == 0) { + isValid = false; + return 0; + } + else return left / right; + } + case '^': { + return fastpow(left, right); + } + default: return 0; + } + } + return 0; + } + void print(){ + inorder(root); + } +}; + +int main(){ + string s; + while(getline(cin, s)){ + if (s.empty()) { + cout << "INVALID" << endl; + continue; + } + Expression tree(s); + tree.root = tree.build(s, 0, s.length()-1); + if (!tree.root) { + cout << "INVALID" << endl; + continue; + } + long long result = tree.calc(tree.root, tree.isValid); + if(tree.isValid) cout << result << endl; + else cout << "INVALID" << endl; + } + return 0; +} diff --git a/Exercise/Homework3/Q2.rs b/Exercise/Homework3/Q2.rs new file mode 100644 index 0000000..4aa2f85 --- /dev/null +++ b/Exercise/Homework3/Q2.rs @@ -0,0 +1,34 @@ +use std::io; + +fn main(){ + let core = "edgnb"; + let mut s = String::new(); + io::stdin().read_line(&mut s).unwrap(); + let mut n: i32 = s.trim().parse().unwrap(); + + for i in 0..n{ + let mut js = 0; + let mut cnt = 0; + let mut str = String::new(); + io::stdin().read_line(&mut str).unwrap(); + let mut num = String::new(); + io::stdin().read_line(&mut num).unwrap(); + let mut m: i32 = num.trim().parse().unwrap(); + + let mut j = 0; + while j <= str.len() - 5{ + if &str[j..j+5] == core { + js += 1; + j += 5; + if js >= m { + cnt += 1; + } + } else{ + js = 0; + j += 1; + } + } + + println!("{}", cnt); + } +} \ No newline at end of file diff --git a/Exercise/Homework3/Q3.rs b/Exercise/Homework3/Q3.rs new file mode 100644 index 0000000..7b8c251 --- /dev/null +++ b/Exercise/Homework3/Q3.rs @@ -0,0 +1,79 @@ +use std::io::{self, BufRead}; + + +fn next(s: &Vec, start: usize, end: usize) -> Vec { + let n = end - start; + let mut nxt = vec![0; n]; + let mut j = 0; + for i in 1..n { + while j > 0 && s[start + i] != s[start + j] { + j = nxt[j - 1]; + } + if s[start + i] == s[start + j] { + j += 1; + } + nxt[i] = j; + } + nxt +} + +fn main(){ +let stdin = io::stdin(); +for line in stdin.lock().lines() { + let s = line.unwrap(); + if s.trim().is_empty() { continue; } + + let c: Vec = s.trim().chars().collect(); + let n = c.len(); + let mut nxt = next(&c, 0, c.len()); + let mut plen = -1; + + //计算P的话可以直接用最长后缀算,使用KMP + for len in (1..n).rev() { + let mode: Vec = c[n - len..n].to_vec(); + let tmp: Vec = next(&mode, 0, mode.len()); + let mut i = 0; + let mut j = 0; + while i < n - 1 { + while j > 0 && c[i] != mode[j] { + j = tmp[j - 1]; + } + if c[i] == mode[j] { + j += 1; + } + if j == mode.len() { + plen = mode.len() as i32; + break; + } + if plen > 0 { + break; + } + i += 1; + } + if plen > 0 { + break; + } + } + + //计算Q,用len1和len2,如果2 * qlen > len(s),则len(Q) = 0 + + let mut qlen = 0; + if nxt[n - 1] > 0 { + qlen = nxt[nxt[n - 1] - 1]; + } + if 2 * qlen > n { + qlen = 0; + } else { + qlen = n - 2 * qlen; + } + + if plen < 0 { + plen = 0; + } + let out = qlen as i32 + plen as i32; + println!("{}", out); + + //println!("qlen: {}", qlen); + //println!("plen: {}", plen); +} +} \ No newline at end of file diff --git a/Exercise/Homework3/grok的表达式树模板.cpp b/Exercise/Homework3/grok的表达式树模板.cpp new file mode 100644 index 0000000..2d39383 --- /dev/null +++ b/Exercise/Homework3/grok的表达式树模板.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include + +enum class NodeType { + OPERAND, // + OPERATOR // +}; + +class ExprNode { +public: + NodeType node_type; + std::unique_ptr left; + std::unique_ptr right; + + virtual ~ExprNode() = default; + virtual std::string toString() const = 0; +}; + +class OperandNode : public ExprNode { +public: + int value; + + OperandNode(int val) : value(val) { + node_type = NodeType::OPERAND; + } + + std::string toString() const override { + return "Operand(" + std::to_string(value) + ")"; + } +}; + +class OperatorNode : public ExprNode { +public: + std::string op; + + OperatorNode(const std::string& oper, std::unique_ptr l = nullptr, std::unique_ptr r = nullptr) + : op(oper) { + node_type = NodeType::OPERATOR; + left = std::move(l); + right = std::move(r); + } + + std::string toString() const override { + std::string left_str = left ? " " + left->toString() : ""; + std::string right_str = right ? " " + right->toString() : ""; + return "Operator(" + op + left_str + right_str + ")"; + } +}; + +class ExprTree { +private: + std::unique_ptr root; + +public: + ExprTree(std::unique_ptr r = nullptr) : root(std::move(r)) {} + + void setRoot(std::unique_ptr r) { + root = std::move(r); + } + + // ʾInorder Traversalڴӡʽ + void inorderTraversal(const std::unique_ptr& node, std::vector& result) const { + if (!node) return; + inorderTraversal(node->left, result); + if (node->node_type == NodeType::OPERAND) { + auto operand = static_cast(node.get()); + result.push_back(std::to_string(operand->value)); + } else { + auto oper = static_cast(node.get()); + result.push_back(oper->op); + } + inorderTraversal(node->right, result); + } + + std::string toInfixString() const { + std::vector result; + inorderTraversal(root, result); + if (result.empty()) return ""; + // ʵ账ȷʾȼ + std::string infix; + for (const auto& s : result) { + infix += s + " "; + } + return infix.substr(0, infix.size() - 1); // Ƴĩβո + } + + // ʾӼ׺ʽ򻯰棬ֻ֧ + - * / ţ + // ע⣺һʵ֣ʹõݹ½չ + static std::unique_ptr buildFromInfix(const std::string& expr, size_t& pos) { + // ո + while (pos < expr.size() && expr[pos] == ' ') ++pos; + + if (pos >= expr.size()) return nullptr; + + char ch = expr[pos]; + if (isdigit(ch)) { + // + int num = 0; + while (pos < expr.size() && isdigit(expr[pos])) { + num = num * 10 + (expr[pos++] - '0'); + } + return std::make_unique(num); + } else if (ch == '(') { + ++pos; // '(' + auto left = buildFromInfix(expr, pos); + auto op_node_raw = buildFromInfix(expr, pos); // + auto right = buildFromInfix(expr, pos); + if (pos < expr.size() && expr[pos] == ')') ++pos; + if (op_node_raw && op_node_raw->node_type == NodeType::OPERATOR) { + auto op_node = std::unique_ptr(static_cast(op_node_raw.release())); + op_node->left = std::move(left); + op_node->right = std::move(right); + return std::move(op_node); + } + return nullptr; // + } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') { + std::string oper(1, expr[pos++]); + return std::make_unique(oper); + } + return nullptr; + } + + // ݷַ + void buildFromInfix(const std::string& expr) { + size_t pos = 0; + root = buildFromInfix(expr, pos); + } +}; + +// ʾʹ +int main() { + // ֶ3 + (4 * 5) + auto mul = std::make_unique("*"); + mul->left = std::make_unique(4); + mul->right = std::make_unique(5); + + auto add = std::make_unique("+"); + add->left = std::make_unique(3); + add->right = std::move(mul); + + ExprTree tree(std::move(add)); + std::cout << "ʾ: " << tree.root->toString() << std::endl; + std::cout << ": " << tree.toInfixString() << std::endl; // "3 + * 4 5" + + // ַ򻯣֧֣ + ExprTree tree2; + tree2.buildFromInfix("3+(4*5)"); // ҪƽԴʽ + std::cout << "ַ: " << (tree2.root ? tree2.root->toString() : "Ч") << std::endl; + + return 0; +} diff --git a/Exercise/Homework3/表达式树模板.cpp b/Exercise/Homework3/表达式树模板.cpp new file mode 100644 index 0000000..d7b0fd1 --- /dev/null +++ b/Exercise/Homework3/表达式树模板.cpp @@ -0,0 +1,146 @@ +#include +using namespace std; + +struct Node { + char sign; // ҶӽڵΪ '?' + long long num; // + Node* left; + Node* right; + + Node(): sign('?'), num(-1), left(nullptr), right(nullptr) {} + Node(char s): sign(s), num(-1), left(nullptr), right(nullptr) {} + Node(long long n): sign('?'), num(n), left(nullptr), right(nullptr) {} +}; + +// ݣ +long long fastpow(long long base, long long exp){ + long long res = 1; + while(exp > 0){ + if(exp & 1) res *= base; + base *= base; + exp >>= 1; + } + return res; +} + +// ȼ +int level(char c){ + switch(c){ + case '+': case '-': return 1; + case '*': case '/': return 2; + case '^': return 3; + default: return 0; + } +} + +// ҵȼ͵ +int findexp(const string &s, int l, int r){ + int pos = -1; + int minLevel = 114514; + int balance = 0; // + for(int i = r; i >= l; --i){ // ҽϣұ + if(s[i] == ')') balance++; + else if(s[i] == '(') balance--; + else if(balance == 0 && level(s[i]) > 0){ + if(level(s[i]) <= minLevel){ + minLevel = level(s[i]); + pos = i; + } + } + } + return pos; +} + +// ַת +long long toNum(const string &s, int l, int r){ + long long tmp = 0; + while(l <= r && isspace((unsigned char)s[l])) l++; + while(r >= l && isspace((unsigned char)s[r])) r--; + if(l > r) return 0; + for(int i = l; i <= r; ++i){ + if(!isdigit(s[i])) return 0; + tmp = tmp * 10 + (s[i] - '0'); + } + return tmp; +} + +class Expression { +public: + string exp; + Node* root; + long long result; + bool isValid; + + Expression(const string &s): exp(s), root(nullptr), result(0), isValid(true) {} + + Node* build(const string &s, int l, int r){ + while(l <= r && s[l] == ' ') l++; + while(l <= r && s[r] == ' ') r--; + if(l > r) return nullptr; + + // Ŵ + if(s[l] == '(' && s[r] == ')'){ + int balance = 0; + bool hasOuter = true; + for(int i = l; i <= r; ++i){ + if(s[i] == '(') balance++; + else if(s[i] == ')') balance--; + if(balance == 0 && i < r){ + hasOuter = false; + break; + } + } + if(hasOuter) return build(s, l+1, r-1); + } + + int pos = findexp(s, l, r); + if(pos == -1){ + long long val = toNum(s, l, r); + return new Node(val); + } + + Node* tmp = new Node(s[pos]); + tmp->left = build(s, l, pos-1); + tmp->right = build(s, pos+1, r); + return tmp; + } + + long long calc(Node* r, bool &v){ + if(!r) return 0; + if(r->sign == '?') return r->num; + + long long left = calc(r->left, v); + long long right = calc(r->right, v); + + switch(r->sign){ + case '+': return left + right; + case '-': return left - right; + case '*': return left * right; + case '/': + if(right == 0){ v = false; return 0; } + return left / right; + case '^': + if(right < 0){ v = false; return 0; } + return fastpow(left, right); + default: return 0; + } + } + + void calc(){ + isValid = true; + result = calc(root, isValid); + } +}; + +int main(){ + string s; + while(getline(cin, s)){ + Expression tree(s); + tree.root = tree.build(s, 0, s.length()-1); + tree.calc(); + if(tree.isValid) cout << tree.result << endl; + else cout << "INVALID" << endl; + } + return 0; +} +