Skip to content

Commit 860c471

Browse files
committed
QOJ: Deep Abyss
1 parent 45c3645 commit 860c471

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

QOJ/8470.cpp

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/**
2+
* @file 8470.cpp
3+
* @author Macesuted ([email protected])
4+
* @date 2025-10-06
5+
*
6+
* @copyright Copyright (c) 2025
7+
*
8+
*/
9+
10+
#include <bits/stdc++.h>
11+
using namespace std;
12+
13+
#ifndef LOCAL
14+
#define endl '\n'
15+
#endif
16+
17+
bool mem1;
18+
19+
using Mbit = bitset<129>;
20+
using M = array<Mbit, 128>;
21+
22+
unordered_map<string, M> val;
23+
M Mzero;
24+
25+
M bitNot(M b) {
26+
for (size_t i = 0; i < 128; i++) b[i][128] = !b[i][128];
27+
return b;
28+
}
29+
M bitOr(M b, M v) {
30+
for (size_t i = 0; i < 128; i++) assert(v[i].count() == v[i][128]);
31+
for (size_t i = 0; i < 128; i++)
32+
if (v[i][128]) b[i] = 0, b[i][128] = true;
33+
return b;
34+
}
35+
M bitAnd(M b, M v) {
36+
for (size_t i = 0; i < 128; i++) assert(v[i].count() == v[i][128]);
37+
for (size_t i = 0; i < 128; i++)
38+
if (!v[i][128]) b[i] = 0;
39+
return b;
40+
}
41+
M bitXor(M b, M v) {
42+
for (size_t i = 0; i < 128; i++) b[i] ^= v[i];
43+
return b;
44+
}
45+
46+
M readHex(string s) {
47+
M ans = Mzero;
48+
49+
reverse(s.begin(), s.end());
50+
for (size_t i = 0; i < s.size() - 2; i++) {
51+
int v = ('0' <= s[i] && s[i] <= '9' ? s[i] - '0' : 10 + s[i] - 'a');
52+
for (size_t j = 0; j < 4; j++) ans[i << 2 | j][128] = v >> j & 1;
53+
}
54+
55+
return ans;
56+
}
57+
M readVar(string s) { return val[s]; }
58+
M readTerm(string s) {
59+
bool rev = false;
60+
if (s[0] == '~') s = s.substr(1), rev = true;
61+
M ans = s[0] == '0' ? readHex(s) : readVar(s);
62+
if (rev) ans = bitNot(ans);
63+
return ans;
64+
}
65+
66+
void solve(void) {
67+
string code;
68+
69+
for (int i = 0; i < 128; i++) Mzero[i] = 0;
70+
71+
M& x = val["x"] = Mzero;
72+
for (int i = 0; i < 128; i++) x[i][i] = true;
73+
74+
while (getline(cin, code)) {
75+
stringstream ssin(code);
76+
77+
string var, eq, lef, op, rig;
78+
ssin >> var >> eq >> lef;
79+
80+
if (!(ssin >> op)) {
81+
val[var] = readTerm(lef);
82+
continue;
83+
}
84+
85+
ssin >> rig;
86+
87+
if (op == "<<" || op == ">>") {
88+
M l = readTerm(lef);
89+
int r = stoi(rig);
90+
91+
val[var] = Mzero;
92+
for (int i = 0; i < 128; i++) {
93+
int j = (op == "<<" ? i - r : i + r);
94+
if (0 <= j && j < 128) val[var][i] = l[j];
95+
}
96+
} else {
97+
if (lef[0] == '0' || (lef[0] == '~' && lef[1] == '0')) swap(lef, rig);
98+
M l = readTerm(lef), r = readTerm(rig);
99+
100+
if (op == "&")
101+
val[var] = bitAnd(l, r);
102+
else if (op == "|")
103+
val[var] = bitOr(l, r);
104+
else
105+
val[var] = bitXor(l, r);
106+
}
107+
}
108+
109+
M base = Mzero;
110+
for (int i = 0; i < 128; i++) {
111+
x[i][i] = !x[i][i];
112+
for (int j = 0; j < 128; j++)
113+
if (x[i][j]) {
114+
if (base[j].count())
115+
x[i] ^= base[j];
116+
else {
117+
base[j] = x[i], x[i] = 0;
118+
for (int x = j + 1; x < 128; x++)
119+
if (base[j][x]) base[j] ^= base[x];
120+
for (int x = 0; x < j; x++)
121+
if (base[x][j]) base[x] ^= base[j];
122+
break;
123+
}
124+
}
125+
if (x[i].count()) return cout << ":(" << endl, void();
126+
}
127+
128+
vector<int> ans(32);
129+
for (size_t i = 0; i < 128; i++) ans[i >> 2] |= base[i][128] << (i & 3);
130+
131+
string os;
132+
for (int i = 31; ~i; i--) os.push_back(ans[i] < 10 ? '0' + ans[i] : 'a' + ans[i] - 10);
133+
while (os.size() > 1 && os[0] == '0') os.erase(0, 1);
134+
135+
cout << "0x" << os << endl;
136+
137+
return;
138+
}
139+
140+
bool mem2;
141+
142+
int main() {
143+
ios::sync_with_stdio(false), cin.tie(nullptr);
144+
#ifdef LOCAL
145+
cerr << "Memory Cost: " << abs(&mem1 - &mem2) / 1024. / 1024. << "MB" << endl;
146+
#endif
147+
148+
int _ = 1;
149+
while (_--) solve();
150+
151+
#ifdef LOCAL
152+
cerr << "Time Cost: " << clock() * 1000. / CLOCKS_PER_SEC << "MS" << endl;
153+
#endif
154+
return 0;
155+
}

0 commit comments

Comments
 (0)