Submission #677156

#TimeUsernameProblemLanguageResultExecution timeMemory
677156stanislavpolynHomework (CEOI22_homework)C++17
53 / 100
334 ms392032 KiB
#include <bits/stdc++.h> #define fr(i, a, b) for (int i = (a); i <= (b); ++i) #define rf(i, a, b) for (int i = (a); i >= (b); --i) #define fe(x, y) for (auto& x : y) #define fi first #define se second #define pb push_back #define mp make_pair #define mt make_tuple #define all(x) (x).begin(), (x).end() #define pw(x) (1LL << (x)) #define sz(x) (int)(x).size() using namespace std; mt19937_64 rng(228); #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; template <typename T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; #define fbo find_by_order #define ook order_of_key template <typename T> bool umn(T& a, T b) { return a > b ? (a = b, 1) : 0; } template <typename T> bool umx(T& a, T b) { return a < b ? (a = b, 1) : 0; } using ll = long long; using ld = long double; using pii = pair<int, int>; using pll = pair<ll, ll>; template <typename T> using ve = vector<T>; #ifndef LOCAL const int N = 5e6 + 5; #else const int N = 1005; #endif string s; int last[N]; int p[N]; int root; ve<int> g[N]; int n; ve<int> pos; int val[N]; ve<int> ver; ve<int> order; int sz[N]; int inc[N]; void dfs(int v) { if (sz(g[v]) == 0) { sz[v] = 1; } fe (to, g[v]) { dfs(to); sz[v] += sz[to]; } order.pb(v); } pii dp[N][2]; int L, R; void DFS(int v) { if (!sz(g[v])) { inc[L]++; inc[R + 1]--; return; } int to1 = g[v][0]; int to2 = g[v][1]; if (s[v - 1] == 'x') { L += sz[to1] - dp[to1][0].se; R += sz[to1] - dp[to1][0].fi; DFS(to2); L -= sz[to1] - dp[to1][0].se; R -= sz[to1] - dp[to1][0].fi; } else { L += dp[to1][1].fi; R += dp[to1][1].se; DFS(to2); L -= dp[to1][1].fi; R -= dp[to1][1].se; } swap(to1, to2); if (s[v - 1] == 'x') { L += sz[to1] - dp[to1][0].se; R += sz[to1] - dp[to1][0].fi; DFS(to2); L -= sz[to1] - dp[to1][0].se; R -= sz[to1] - dp[to1][0].fi; } else { L += dp[to1][1].fi; R += dp[to1][1].se; DFS(to2); L -= dp[to1][1].fi; R -= dp[to1][1].se; } } int main() { #ifdef LOCAL freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); #else ios::sync_with_stdio(0); cin.tie(0); #endif cin >> s; last[0] = -1; int bal = 0; fr (i, 0, sz(s) - 1) { if (s[i] == '(' || s[i] == ')') { if (s[i] == '(') { bal++; } else { bal--; } if (s[i] == '(') { p[i] = last[bal - 1]; last[bal] = i; } } if (s[i] == '?') { pos.pb(i); p[i] = last[bal]; n++; } } fr (i, 0, sz(s) - 1) { if (s[i] == '(' || s[i] == '?') { if (p[i] == -1) { root = i; } else { g[p[i]].pb(i); } ver.pb(i); // cout << i << " " << s[i - 1] << "\n"; } } dfs(root); { fe (v, order) { if (sz(g[v]) == 0) { dp[v][0] = {0, 0}; dp[v][1] = {0, 0}; continue; } int to1 = g[v][0]; int to2 = g[v][1]; if (s[v - 1] == 'x') { dp[v][0] = {dp[to1][0].fi + dp[to2][0].fi, dp[to1][0].se + dp[to2][0].se}; dp[v][1] = {1e9, -1e9}; umn(dp[v][1].fi, dp[to1][1].fi + dp[to2][1].fi); umn(dp[v][1].fi, dp[to1][1].fi + (sz[to2] - dp[to2][0].se)); umn(dp[v][1].fi, (sz[to1] - dp[to1][0].se) + dp[to2][1].fi); umx(dp[v][1].se, dp[to1][1].se + dp[to2][1].se); umx(dp[v][1].se, dp[to1][1].se + (sz[to2] - dp[to2][0].fi)); umx(dp[v][1].se, (sz[to1] - dp[to1][0].fi) + dp[to2][1].se); } else { dp[v][1] = {dp[to1][1].fi + dp[to2][1].fi, dp[to1][1].se + dp[to2][1].se}; dp[v][0] = {1e9, -1e9}; umn(dp[v][0].fi, dp[to1][0].fi + dp[to2][0].fi); umn(dp[v][0].fi, dp[to1][0].fi + (sz[to2] - dp[to2][1].se)); umn(dp[v][0].fi, (sz[to1] - dp[to1][1].se) + dp[to2][0].fi); umx(dp[v][0].se, dp[to1][0].se + dp[to2][0].se); umx(dp[v][0].se, dp[to1][0].se + (sz[to2] - dp[to2][1].fi)); umx(dp[v][0].se, (sz[to1] - dp[to1][1].fi) + dp[to2][0].se); } } } // cout << dp[3][0].fi << " " << dp[3][0].se << " " << dp[3][1].fi << " " << dp[3][1].se << "\n"; { DFS(root); // fr (x, 1, n) { // fr (me, 0, sz(pos) - 1) { // int v = pos[me]; // // int L = 0; // int R = 0; // //// cout << "start " << v << "\n"; // // int last = -1; // while (1) { // if (sz(g[v])) { // //// cout << "GO " << v << "\n"; // int to1 = g[v][0]; // int to2 = g[v][1]; // // if (to1 == last) swap(to1, to2); // // if (s[v - 1] == 'x') { // L += sz[to1] - dp[to1][0].se; // R += sz[to1] - dp[to1][0].fi; // } else { // L += dp[to1][1].fi; // R += dp[to1][1].se; // } //// cout << "dp: " << dp[to1][1].se << "\n"; //// cout << "to1: " << to1 << "\n"; //// cout << "l, r: " << L << " " << R << "\n"; // } // // if (v == root) break; // last = v; // v = p[v]; // } // //// cout << pos[me] << " " << L << " " << R << "\n"; // inc[L]++; // inc[R + 1]--; // } fr (i, 1, n) inc[i] += inc[i - 1]; int ans = 0; fr (i, 0, n - 1) { if (inc[i]) { ans++; } } cout << ans << "\n"; } return 0; ve<bool> possib(n + 1); fr (mask, 0, pw(n - 1) - 1) { fr (me, 0, sz(pos) - 1) { fe (x, ver) val[x] = -1; int x = 1; int ptr = 0; fr (i, 0, n - 2) { if (ptr == me) ptr++; if (mask & pw(i)) { val[pos[ptr++]] = 1; } else { val[pos[ptr++]] = 0; x++; } } val[pos[me]] = 2; bool bad = 0; fe (v, order) { if (s[v] == '?') continue; assert(val[v] == -1); if (val[g[v][1]] == 2) swap(g[v][0], g[v][1]); if (val[g[v][0]] == 2) { if (s[v - 1] == 'x' && val[g[v][1]] == 1) { bad = 1; break; } if (s[v - 1] == 'n' && val[g[v][1]] == 0) { bad = 1; break; } val[v] = 2; } else { if (s[v - 1] == 'x') { val[v] = max(val[g[v][0]], val[g[v][1]]); } else { val[v] = min(val[g[v][0]], val[g[v][1]]); } } } if (!bad) { possib[x] = 1; } } } int ans = 0; fr (i, 1, n) { if (possib[i]) { // cout << i << "\n"; ans++; } } cout << ans << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...