QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#355548 | #7858. Basic Equation Solving | ucup-team1191# | TL | 435ms | 3944kb | C++20 | 9.2kb | 2024-03-16 20:10:22 | 2024-10-14 18:03:09 |
Judging History
answer
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define TIME (clock() * 1.0 / CLOCKS_PER_SEC)
const int MOD = 998'244'353;
using ull = unsigned long long;
template <int MD>
struct ModInt {
using M = ModInt;
// static int MD;
int v;
ModInt(ll _v = 0) { set_v(int(_v % MD + MD)); }
inline M& set_v(int _v) {
v = (_v < MD) ? _v : _v - MD;
return *this;
}
inline explicit operator bool() const { return v != 0; }
inline M operator-() const { return M() - *this; }
inline M operator+(const M& r) const { return M().set_v(v + r.v); }
inline M operator-(const M& r) const { return M().set_v(v + MD - r.v); }
inline M operator*(const M& r) const { return M().set_v(int((ull)v * r.v % MD)); }
inline M operator/(const M& r) const { return *this * r.inv(); }
inline M& operator+=(const M& r) { return *this = *this + r; }
inline M& operator-=(const M& r) { return *this = *this - r; }
inline M& operator*=(const M& r) { return *this = *this * r; }
inline M& operator/=(const M& r) { return *this = *this / r; }
inline bool operator==(const M& r) const { return v == r.v; }
inline bool operator!=(const M& r) const { return v != r.v; }
inline M inv() const;
inline friend istream& operator>>(istream& is, M& r) { ll x; is >> x; r = M(x); return is; }
inline friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; }
};
template<int MD>
ModInt<MD> pow(ModInt<MD> x, ll n) {
//ModInt pow(ModInt x, ll n) {
ModInt<MD> r = 1;
//ModInt r = 1;
while (n) {
if (n & 1) r *= x;
x *= x;
n >>= 1;
}
return r;
}
template<int MD>
ModInt<MD> ModInt<MD>::inv() const { return pow(*this, MD - 2); }
//ModInt ModInt::inv() const { return pow(*this, MD - 2); }
// if MD is from input
// this line is necessary, read later as you wish
//int ModInt::MD;
using Mint = ModInt<MOD>;
//using Mint = ModInt;
tuple<bool, string, string> read() {
string s;
cin >> s;
int p = -1;
for (int i = 0; i < (int)s.size(); i++) {
if (s[i] == '=' || s[i] == '>' || s[i] == '<') {
p = i;
}
}
assert(p != -1);
auto a = s.substr(0, p);
auto b = s.substr(p + 1, (int)s.size() - p - 1);
while (a.size() < b.size()) {
a = "0" + a;
}
while (b.size() < a.size()) {
b = "0" + b;
}
if (s[p] == '<') {
swap(a, b);
}
return make_tuple(s[p] == '=', a, b);
}
const int S = 36;
int getnum(char x) {
if (x >= '0' && x <= '9') {
return x - '0';
}
return 10 + (x - 'A');
}
int par[S], rg[S];
vector<tuple<int, int, int>> history;
int find_set(int i) {
if (i == par[i]) {
return i;
}
return find_set(par[i]);
}
void merge(int i, int j) {
i = find_set(i);
j = find_set(j);
if (i == j) {
history.emplace_back(-1, -1, -1);
return;
}
if (rg[i] > rg[j]) {
swap(i, j);
}
history.emplace_back(i, par[i], rg[j]);
par[i] = j;
if (rg[i] == rg[j]) {
rg[j]++;
}
}
void undo() {
auto op = history.back();
history.pop_back();
if (get<0>(op) == -1) {
return;
}
int i = get<0>(op);
int j = par[i];
par[i] = get<1>(op);
rg[j] = get<2>(op);
}
bool check_dig() {
ll mask = 0;
for (int i = 0; i < 10; i++) {
ll idx = find_set(i);
if ((mask >> idx) & 1LL) {
return false;
}
mask |= (1LL << idx);
}
return true;
}
vector<pair<int, int>> edges;
int dig[S];
int cnt[S];
int p2[S];
int fnd(int i) {
if (i == p2[i]) {
return i;
}
return p2[i] = fnd(p2[i]);
}
void mrg(int i, int j) {
i = fnd(i);
j = fnd(j);
if (i == j) {
return;
}
p2[i] = j;
}
vector<int> in[S];
vector<pair<int, int>> ein[S];
int into[S];
bool good[(1 << 11)];
bool can[10][(1 << 11)];
Mint dp[2][(1 << 11)];
Mint func(int cmp) {
if (ein[cmp].empty()) {
int x = in[cmp][0];
if (dig[x] != -1) {
return 1;
} else {
return 10;
}
}
int sz = in[cmp].size();
for (int i = 0; i < sz; i++) {
into[in[cmp][i]] = i;
}
for (int mask = 0; mask < (1 << sz); mask++) {
good[mask] = true;
for (auto [s, f] : ein[cmp]) {
s = into[s];
f = into[f];
if (((mask >> f) & 1) == 1 && ((mask >> s) & 1) == 0) {
good[mask] = false;
break;
}
}
}
for (int d = 0; d < 10; d++) {
for (int mask = 0; mask < (1 << sz); mask++) {
can[d][mask] = true;
for (int s : in[cmp]) {
int u = dig[s];
if (u != -1) {
s = into[s];
if ((mask >> s) & 1) {
if (u != d) {
can[d][mask] = false;
break;
}
}
}
}
if (!can[d][mask]) {
continue;
}
for (auto [s, f]: ein[cmp]) {
s = into[s];
f = into[f];
if (((mask >> f) & 1) == 1 && ((mask >> s) & 1) == 1) {
can[d][mask] = false;
break;
}
}
}
}
memset(dp[0], 0, sizeof(dp[0]));
dp[0][0] = 1;
for (int d = 9; d >= 0; d--) {
memset(dp[d & 1], 0, sizeof(dp[d & 1]));
for (int mask = 0; mask < (1 << sz); mask++) {
if (good[mask]) {
for (int sub = mask; sub > 0; sub = (sub - 1) & mask) {
if (good[sub] && can[d][sub ^ mask]) {
dp[d & 1][mask] += dp[(d + 1) & 1][sub];
}
}
{
int sub = 0;
if (good[sub] && can[d][sub ^ mask]) {
dp[d & 1][mask] += dp[(d + 1) & 1][sub];
}
}
}
}
}
return dp[0][(1 << sz) - 1];
}
Mint calc() {
memset(dig, -1, sizeof(dig));
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i < 10; i++) {
int c = find_set(i);
dig[c] = i;
}
for (int i = 10; i < S; i++) {
int c = find_set(i);
cnt[c]++;
}
for (int i = 0; i < S; i++) {
p2[i] = i;
}
for (const auto& t : edges) {
int x = find_set(t.first);
int y = find_set(t.second);
if (x == y) {
return 0;
}
mrg(x, y);
}
for (int i = 0; i < S; i++) {
in[i].clear();
ein[i].clear();
}
for (int i = 0; i < S; i++) {
if (cnt[i] > 0 || dig[i] != -1) {
in[fnd(i)].emplace_back(i);
}
}
for (const auto& t : edges) {
int x = find_set(t.first);
int y = find_set(t.second);
int cmp = fnd(x);
ein[cmp].emplace_back(x, y);
}
Mint ans = 1;
for (int x = 0; x < S; x++) {
if (!in[x].empty()) {
auto val = func(x);
//cerr << x << " " << val << "??\n";
ans *= val;
if (ans == 0) {
return 0;
}
}
}
return ans;
}
Mint ans;
vector<pair<string, string>> pr;
void gen(int b) {
if (b == pr.size()) {
ans += calc();
return;
}
int cnt = pr[b].first.size();
for (int i = 0; i < (int)pr[b].first.size(); i++) {
int x = getnum(pr[b].first[i]);
int y = getnum(pr[b].second[i]);
edges.emplace_back(x, y);
gen(b + 1);
edges.pop_back();
merge(x, y);
if (!check_dig()) {
cnt = i + 1;
break;
}
}
for (int it = 0; it < cnt; it++) {
undo();
}
}
void solve() {
int n;
cin >> n;
vector<tuple<bool, string, string>> constr;
for (int i = 0; i < n; i++) {
constr.emplace_back(read());
//cout << get<0>(constr.back()) << " " << get<1>(constr.back()) << " " << get<2>(constr.back()) << "\n";
}
iota(par, par + S, 0);
memset(rg, 0, sizeof(rg));
pr.clear();
for (const auto& item : constr) {
if (get<0>(item)) {
auto a = get<1>(item);
auto b = get<2>(item);
for (int i = 0; i < (int)a.size(); i++) {
merge(getnum(a[i]), getnum(b[i]));
}
} else {
pr.emplace_back(get<1>(item), get<2>(item));
}
}
if (!check_dig()) {
cout << "0\n";
return;
}
ans = 0;
gen(0);
cout << ans << "\n";
}
int main() {
#ifdef ONPC
freopen("input", "r", stdin);
#endif
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t = 1;
//cin >> t;
while (t--) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3620kb
input:
1 P=NP
output:
766136394
result:
ok single line: '766136394'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3704kb
input:
1 2000CNY>3000USD
output:
0
result:
ok single line: '0'
Test #3:
score: 0
Accepted
time: 0ms
memory: 3864kb
input:
4 AB>CD E<A BC>FF EF>F1
output:
23645065
result:
ok single line: '23645065'
Test #4:
score: 0
Accepted
time: 0ms
memory: 3676kb
input:
2 BC>DD BD<EA
output:
27271695
result:
ok single line: '27271695'
Test #5:
score: 0
Accepted
time: 0ms
memory: 3864kb
input:
3 CE>ED CC>BA BB<AC
output:
426829091
result:
ok single line: '426829091'
Test #6:
score: 0
Accepted
time: 8ms
memory: 3644kb
input:
10 KG<EI EJ>DA EB<IH EB>JG KF<CF JC>FC IC<BJ FI>HH KD>AH AE>GJ
output:
87744507
result:
ok single line: '87744507'
Test #7:
score: 0
Accepted
time: 21ms
memory: 3904kb
input:
10 EK<GM EL<DC DH>IH EF>BL IM<LL EH<JA DJ<AL GL>MB DB>FM AI<HA
output:
665533468
result:
ok single line: '665533468'
Test #8:
score: 0
Accepted
time: 39ms
memory: 3676kb
input:
10 OD<FK FJ>NL NH>KB KM>CA CI>JH CI<AH CE>GI CO<EG FA>HA FA<IJ
output:
878923575
result:
ok single line: '878923575'
Test #9:
score: 0
Accepted
time: 435ms
memory: 3712kb
input:
10 YH>UQ UQ>FD YZ>MK FY<GO YV<QW UV<VJ UZ>EB EQ>LX VP>ZF LZ>TS
output:
867624189
result:
ok single line: '867624189'
Test #10:
score: 0
Accepted
time: 330ms
memory: 3588kb
input:
10 YH<UL UD<FY FK<MU MM<GO GG<QW QJ<VQ VZ<EB EG<LX LZ<ZP ZV<TS
output:
57935948
result:
ok single line: '57935948'
Test #11:
score: 0
Accepted
time: 1ms
memory: 3936kb
input:
6 EDDC>AB5A B<C E9A9B>CACAA DE2>A0D DBCDAC>AED3D5 AAA>BB5
output:
169889581
result:
ok single line: '169889581'
Test #12:
score: 0
Accepted
time: 0ms
memory: 3636kb
input:
9 C<B A>B FDF2<FBDB DB>B4 CF>DA EF4<D1A B8<A5 B3>BF FFA<D5B
output:
0
result:
ok single line: '0'
Test #13:
score: 0
Accepted
time: 0ms
memory: 3940kb
input:
5 SP6<GCT J0RFZ<ZZLUX UDY7<UEVX C1CQ>FXTG SOCT07<MEABU8
output:
603602671
result:
ok single line: '603602671'
Test #14:
score: 0
Accepted
time: 3ms
memory: 3940kb
input:
7 F>M G8F<KC5 F06<E8G H5J<BJE M8CDE<DIGMC AE08>EFI7 DM>CI
output:
821791712
result:
ok single line: '821791712'
Test #15:
score: 0
Accepted
time: 2ms
memory: 3944kb
input:
10 PS1>O9O G76>F8S J<S SB>Y4 WS<VM E<N ZR<CV G8T>XPJ J<A KT<LS
output:
97272892
result:
ok single line: '97272892'
Test #16:
score: 0
Accepted
time: 0ms
memory: 3676kb
input:
4 K1TVV0>TOB4QTH E5U5C9>QGDEGU Q9LW3SK>LWFRP DXUQM=V4N4
output:
467745652
result:
ok single line: '467745652'
Test #17:
score: 0
Accepted
time: 1ms
memory: 3636kb
input:
5 BC5F<AC3F FA4<D48306EDD EFDD>FDABE CF5C<AFDDB FAF<C387
output:
808992671
result:
ok single line: '808992671'
Test #18:
score: 0
Accepted
time: 0ms
memory: 3644kb
input:
1 ABCDEFGHIJKLMNOPQRSTUVWX>BCDEFGHIJKLMNOPQRSTUVWXY
output:
835948861
result:
ok single line: '835948861'
Test #19:
score: 0
Accepted
time: 0ms
memory: 3676kb
input:
3 A=A 00109=109 XX=Z
output:
276262510
result:
ok single line: '276262510'
Test #20:
score: 0
Accepted
time: 0ms
memory: 3676kb
input:
2 ABCDEFGHIJKL=CDEFGHIJKLMN OPQRSTUVWXYZ=RSTUVWXYZOPQ
output:
100000
result:
ok single line: '100000'
Test #21:
score: 0
Accepted
time: 4ms
memory: 3900kb
input:
9 N=A8 TT<QO3G LS>JV TSG>U5F D<A934 FK<HKG O>S1 GT<BBCX SG>S
output:
929594610
result:
ok single line: '929594610'
Test #22:
score: 0
Accepted
time: 0ms
memory: 3680kb
input:
0
output:
673653469
result:
ok single line: '673653469'
Test #23:
score: 0
Accepted
time: 0ms
memory: 3936kb
input:
3 AB<CD AC<BD AD<BC
output:
219041723
result:
ok single line: '219041723'
Extra Test:
score: -3
Extra Test Failed : Time Limit Exceeded on 4
input:
10 A<BCD E<FGH I<JKL M<NOP Q<RST U<VWX Y<ZAB C<DEF G<HIJ K<LMN