This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 = 1e7 + 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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |