1 条题解
-
0
自动搬运
来自洛谷,原作者为

伟大的王夫子
hanser忠实粉丝,爱好ACG、古风搬运于
2025-08-24 22:27:54,当前版本为作者最后更新于2022-01-16 19:25:21,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
本题就是一个裸的中缀表达式求值。在本题中,我们可以写一个结构体,来存储表示一个数的值( 或者 ,其中 。
对于中缀表达式求值,有一个很好的方法就是先转化为计算机好算的后缀表达式。
那么究竟如何才能实现这个转化呢?
这里我给大家讲一个很常规的做法。
- 建立一个用于存运算符的栈,逐一扫描该中缀表达式中的元素。
- 如果遇到一个数,输出该数。
- 如果遇到左括号,把左括号入栈。
- 如果遇到右括号,不断取出栈顶并输出,直到栈顶为左括号,然后再把左括号出栈。
- 如果遇到运算符,只要栈顶符号的优先级不低于新符号,就不断取出栈顶并输出,最后把新符号入栈。优先级为乘法 > 加减法 > 左括号。
- 依次取出并输出栈中所有剩余符号,最终输出序列就是一个与原中缀表达式等价的一个后缀表达式。
然后在求的时候,注意各个数的顺序,否则会因为减法不满足交换律而错的很惨。
#include <bits/stdc++.h> using namespace std; template <class T> inline void Rd(T &x) { x = 0; bool f = 0; char ch = getchar(); while (!isdigit(ch)) f |= ch == '-', ch = getchar(); while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar(); if (f) x = -x; } typedef long long ll; struct P { ll a, b; }; ll M, PP; P operator*(const P &a, const ll &b) { P c = a; c.a *= b, c.b *= b; c.a %= M, c.b %= M; return c; } P operator*=(P &a, const ll &b) { a = a * b; return a; } P operator+(const P &a, const P &b) { P c; c.a = a.a + b.a, c.b = a.b + b.b; c.a %= M, c.b %= M; return c; } P operator+(const P &a, const int &b) { P c; c.a = a.a, c.b = a.b + b; c.b %= M; return c; } P operator-(const P &a, const int &b) { P c; c.a = a.a, c.b = a.b - b; c.b = ((c.b + M) % M + M) % M; return c; } P operator-(const P &a, const P &b) { P c; c.a = ((a.a - b.a + M) % M + M) % M; c.b = ((a.b - b.b + M) % M + M) % M; return c; } string a; struct shizi { ll x; P a; char ch; int t; shizi() { ch = 0; x = 0; } } b[100005], s[100005]; int m, p; int prior(char ch) { if (ch == '(') return 1; if (ch == '+' || ch == '-') return 2; if (ch == '*') return 3; } ll calc(ll a, ll b, char ch) { if (ch == '*') return a * b % M; if (ch == '+') return (a + b) % M; if (ch == '-') return ((a - b + M) % M + M) % M; } P operator - (const int &a, const P &b) { P c = b; c.b = ((a - c.b) % M + M) % M; c.a = (-c.a % M + M) % M; return c; } int main() { ll x = 0; cin >> a >> PP >> M; for (int i = 0; i < a.size(); ++i) { if (a[i] == 'x') { b[++m].a.a = 1; b[m].t = 2; continue; } if (isdigit(a[i])) { x = x * 10 + (a[i] ^ 48); x %= M; if (i == a.size() - 1 || !isdigit(a[i + 1])) b[++m].x = x, x = 0, b[m].t = 1; } else { if (a[i] == '(') s[++p].ch = '(', s[p].t = 3; else if (a[i] == ')') { while (p && s[p].ch != '(') b[++m] = s[p--]; if (s[p].ch == '(') --p; } else { while (p && prior(s[p].ch) >= prior(a[i])) b[++m] = s[p--]; s[++p].ch = a[i], s[p].t = 3; } } } while (p) b[++m] = s[p--]; for (int i = 1; i <= m; ++i) { if (b[i].t != 3) s[++p] = b[i]; else { shizi d = s[p], c = s[p - 1]; shizi e; char ch = b[i].ch; if (c.t == 1 && d.t == 1) e.x = calc(c.x, d.x, b[i].ch), e.t = 1; else if (d.t == 1 && c.t == 2) { if (ch == '*') e.a = c.a * d.x; if (ch == '+') e.a = c.a + d.x; if (ch == '-') e.a = c.a - d.x; e.t = 2; } else if (c.t == 2 && d.t == 2) { if (ch == '+') e.a = c.a + d.a; if (ch == '-') e.a = c.a - d.a; if (ch == '*') cout << 11; e.t = 2; } else { if (ch == '*') e.a = d.a * c.x; if (ch == '+') e.a = d.a + c.x; if (ch == '-') e.a = c.x - d.a; e.t = 2; } p -= 2; s[++p] = e; } } P ans = s[1].a; for (int i = 0; i < M; ++i) if (((ans.a * i + ans.b) % M + M) % M == PP) { printf("%d", i); break; } }
- 1
信息
- ID
- 6371
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者