Submission #1292176

#TimeUsernameProblemLanguageResultExecution timeMemory
1292176cnam9Slon (COCI15_slon)C++20
120 / 120
2 ms1084 KiB
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; constexpr int N = 1e5 + 5; int mod; struct Token { int a; int b; inline bool operator==(const Token &other) const = default; inline void operator+=(const Token &other) { a += other.a; a -= a >= mod ? mod : 0; b += other.b; b -= b >= mod ? mod : 0; } inline void operator-=(const Token &other) { a -= other.a; a += mod & (a >> 31); b -= other.b; b += mod & (b >> 31); } inline void operator*=(const Token &other) { a = ((long long) a * other.b + (long long) b * other.a) % mod; b = (long long) b * other.b % mod; } }; constexpr Token X = {1, 0}; constexpr Token ADD = {-1, 1}; constexpr Token SUB = {-1, 2}; constexpr Token MUL = {-1, 3}; constexpr Token OPEN = {-1, 4}; constexpr Token CLOSE = {-1, 5}; Token charToToken[128]; Token tokens[N]; int nTokens; int pointer; Token evaluate() { vector<Token> myTokens; while (true) { Token token = tokens[pointer++]; if (token == OPEN) { myTokens.push_back(evaluate()); continue; } if (token == CLOSE) { break; } myTokens.push_back(token); } vector<Token> newTokens; bool multiplying = false; for (Token token : myTokens) { if (token == MUL) { multiplying = true; } else if (token == ADD || token == SUB) { multiplying = false; newTokens.push_back(token); } else if (multiplying) { newTokens.back() *= token; } else { newTokens.push_back(token); } } Token result = newTokens.front(); for (int i = 1; i < newTokens.size(); i += 2) { if (newTokens[i] == ADD) { result += newTokens[i + 1]; } else { result -= newTokens[i + 1]; } } return result; } signed main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); // freopen("input.txt", "r", stdin); string expression; cin >> expression; int value; cin >> value >> mod; nTokens = 0; charToToken['x'] = X; charToToken['+'] = ADD; charToToken['-'] = SUB; charToToken['*'] = MUL; charToToken['('] = OPEN; charToToken[')'] = CLOSE; bool is_num = false; int num = 0; for (char c : expression) { if (isdigit(c)) { if (is_num) { num = (num * 10 + c - '0') % mod; } else { is_num = true; num = c - '0'; } } else { if (is_num) { is_num = false; tokens[nTokens++] = {0, num}; } tokens[nTokens++] = charToToken[c]; } } if (is_num) { tokens[nTokens++] = {0, num}; } tokens[nTokens] = CLOSE; pointer = 0; Token root = evaluate(); int a = root.a; int b = (value - root.b + mod) % mod; int d = __gcd(__gcd(a, b), mod); a /= d; b /= d; mod /= d; int phi = 1; int n = mod; for (int p = 2; p * p <= n; p++) { if (n % p) continue; n /= p; phi *= p - 1; while (n % p == 0) { n /= p; phi *= p; } } if (n > 1) { phi *= n - 1; } // b * a ^ (phi - 1) mod m int res = b; for (int k = phi - 1; k; k >>= 1) { if (k & 1) res = (long long) res * a % mod; a = (long long) a * a % mod; } cout << res; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...