#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128;
int main() {
string s; cin >> s;
i128 num = 0, bse = 1;
while (s.back() != '=') {
if (s.back() == '-') {
num = -num;
}
else {
num += bse * (s.back() - '0');
bse *= 10;
}
s.pop_back();
}
s.pop_back();
i128 l = -LLONG_MAX, r = LLONG_MAX;
while (l < r) {
i128 mid = (l + r) / 2;
auto get = [&]() -> i128 {
vector<char> sign;
vector<i128> v;
i128 now = 0;
char lst = ' ';
for (int i = 0; i < (int)s.size(); ++i) {
if (isdigit(s[i])) {
if (lst == ')' || lst == 'x') sign.push_back('*');
now = now * 10 + s[i] - '0';
lst = 'd';
}
else if (lst == 'd') {
v.push_back(now);
now = 0;
}
if (s[i] == 'x') {
if (lst == ')' || lst == 'd') sign.push_back('*');
v.push_back(mid);
lst = 'x';
}
else if (s[i] == '(') {
if (lst == 'd' || lst == 'x' || lst == ')') sign.push_back('*');
sign.push_back('(');
lst = '(';
}
else if (s[i] == '+') {
while (!sign.empty() && sign.back() == '*') {
i128 a = v.back();
v.pop_back();
i128 b = v.back();
v.pop_back();
v.push_back(a * b);
sign.pop_back();
}
sign.push_back('+');
lst = '+';
}
else if (s[i] == '*') {
sign.push_back('*');
lst = '*';
}
else if (s[i] == ')') {
while (sign.back() != '(') {
i128 a = v.back();
v.pop_back();
i128 b = v.back();
v.pop_back();
if (sign.back() == '*') v.push_back(a * b);
else v.push_back(a + b);
sign.pop_back();
}
sign.pop_back();
lst = ')';
}
}
if (lst == 'd') v.push_back(now);
while (!sign.empty()) {
i128 a = v.back();
v.pop_back();
i128 b = v.back();
v.pop_back();
if (sign.back() == '*') v.push_back(a * b);
else v.push_back(a + b);
sign.pop_back();
}
return v.back();
};
i128 t = get();
if (t > num) r = mid - 1;
else if (t < num) l = mid + 1;
else l = r = mid;
}
cout << (ll)l;
}
写的有点乱,但思路很好想,比较模拟的一道题。
左侧的表达式只有加号和乘号,且题干说明是一次函数,说明左侧一定是单调递增的一次函数,因为x已知时求左侧中缀表达式是比较经典的,考虑二分答案,表达式算出的结果和右面的值比较。
有点恶心的是处理不带乘号的乘法。发现添加乘号的情况是有限的,且只和相邻两数(字符)的组合有关。假设数字为d,有 { ")(", ")d", ")x", "x(", "d(", "xd", "dx" } 几种正常中缀表达式不可能出现的情况,在这几种情况出现时,手动在中间插入乘号即可。
理论上需要处理计算过程中的越界问题,虽然题目说了过程不可能超过abs(LLONG_MAX),但是只能保证带入x的时候不越界,如果用的是二分的话就不一定了,于是开了__int128。因为题干说结果肯定在long long范围内,所以最后转成long long输出即可。



京公网安备 11010502036488号