We hope you enjoyed the problems!
Idea: __baozii__, Tobo
Solution: __baozii__
Editorial: __baozii__
For $$$|p_{n-1}-p_n|$$$ to be divisible by $$$n-1$$$, either $$$p_{n-1}=1$$$ and $$$p_n=n$$$, or $$$p_{n-1}=n$$$ and $$$p_n=1$$$. Either way, we can construct $$$p$$$ backwards. For $$$i$$$ from $$$n-2$$$ to $$$1$$$, there will only by one possible choice for $$$p_i$$$, where $$$p_i$$$ is either $$$p_{i+1}-i$$$ or $$$p_{i+1}+i$$$, depending on the parity of $$$i$$$.
for _ in range(int(input())):
n = int(input())
p = [1, n]
used = {1, n}
for i in range(n - 2, 0, -1):
prev = p[-1]
if 1 <= prev - i <= n and prev - i not in used:
p.append(prev - i)
used.add(prev - i)
else:
p.append(prev + i)
used.add(prev + i)
p.reverse()
print(*p)
We can divide the string into segments that contain only zeros. For one segment that is bounded by two ones, the answer is $$$\lfloor \frac{len}{3} \rfloor$$$.
Each new student added to the segment can cover a maximum of $$$3$$$ empty seats (the seat they occupy plus one on each side).
For every $$$3$$$ zeros, we must place exactly $$$1$$$ student to satisfy the condition while keeping the total count minimal.
After placing these $$$\lfloor \frac{len}{3} \rfloor$$$ students, we can let the remaining zeros placed at the boundaries so that they're covered by the neighbor $1$s.
If a segment of zeros is adjacent to the start or the end of the row, we need to introduce extra zeros. This is because in the proof, the boundary that the remaining zeros can be placed are reduced. If the whole string consist of zeors, we need to introduce two zeros. Otherwise, we need to introduce one zero.
By summing up the contributions of the segments, we can solve the answer.
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
std::string s;
std::cin >> s;
s = '1' + s + '1';
int ans = 0;
for (int i = 1, l = 0; i <= n; ++i) {
if (s[i] == '0') {
if (s[i-1] == '1') {
l = i;
}
if (s[i+1] == '1') {
int c = (l == 1) + (i == n);
ans += (i - l + 1 + c) / 3;
}
} else {
++ans;
}
}
std::cout << ans << '\n';
}
int main() {
std::cin.tie(nullptr)->sync_with_stdio(false);
int T;
std::cin >> T;
while (T--) solve();
return 0;
}
Idea: __baozii__
Solution: __baozii__
Editorial: __baozii__
For any array of elements, if you can somehow swap any pair of elements (maybe indirectly), you can always sort the array.
For some $$$i,j$$$ such that $$$|a_i-a_j| \lt k$$$, how to swap them with help from other elements?
for _ in range(int(input())):
n = int(input())
a = list(map(int, input().split()))
b = sorted(a)
if a == b:
print(-1)
continue
print(min(max(a[i] - b[0], b[-1] - a[i]) for i in range(n) if a[i] != b[i]))
2187B - Shortest Statement Ever
Idea: __baozii__
Solution: __baozii__
Editorial: __baozii__, rucaco
Greedy.
Let $$$ x, y \in \mathbb{Z}_{\ge 0} $$$.
We consider the optimization problem
where $$$\&$$$ denotes the bitwise AND operation.
Equivalent Formulation
Define
Define also the restricted optima
Proposition
Equivalently:
There exists an optimal solution $$$(p,q)$$$ such that $$$p = x$$$ or $$$q = y$$$.
Proof of Equivalence
- If an optimal solution satisfies $$$p = x$$$, then its cost equals $$$|y - q|$$$ for some $$$q$$$ with $$$x \& q = 0$$$, hence $$$\mathrm{OPT} = \mathrm{OPT}_x$$$.
- Similarly, if an optimal solution satisfies $$$q = y$$$, then $$$\mathrm{OPT} = \mathrm{OPT}_y$$$.
- Conversely, if the equality holds, the minimizer in the attaining branch gives an optimal solution with $$$p=x$$$ or $$$q=y$$$.
Inductive Proof on Bit-Length
Fix an integer $$$n \ge 1$$$.
Assume
Let
Write the binary decompositions
where
The constraint $$$p \& q = 0$$$ implies:
- $$$p_1$$$ and $$$q_1$$$ cannot both be $$$1$$$,
- $$$p_0 \& q_0 = 0$$$.
Case 1: No Conflict $$$(x_1,y_1) \neq (1,1)$$$
In this case, the highest bit does not force a trade-off.
Lemma 1
If $$$x_1 = 0$$$, then there exists an optimal solution with $$$p_1 = 0$$$. Similarly, if $$$y_1 = 0$$$, there exists an optimal solution with $$$q_1 = 0$$$.
Proof
Assume $$$x_1 = 0$$$ but $$$p_1 = 1$$$. Replace $$$p$$$ by $$$p' = p - W$$$.
- Feasibility: clearing a bit of $$$p$$$ cannot create a new $$$1 \& 1$$$ conflict.
- Optimality: since $$$x \lt W$$$,
Thus $$$p_1$$$ can be set to $$$0$$$ without increasing cost.
The argument for $$$q$$$ is symmetric.
Hence we may assume
The objective becomes
This reduces the problem to the $$$(n-1)$$$-bit instance $$$(x_0,y_0)$$$. By the inductive hypothesis, there exists an optimal solution with $$$p_0 = x_0$$$ or $$$q_0 = y_0$$$, hence $$$p = x$$$ or $$$q = y$$$.
Case 2: Conflict $$$(x_1,y_1) = (1,1)$$$
Now the highest bit conflicts, so
Lemma 2
We could Exclusion of $$$(0,0)$$$.
Proof
Any feasible solution with
satisfies
Moreover, there exists a feasible solution with $$$(p_1,q_1) = (1,0)$$$ and cost
Since $$$x = W + x_0 \gt p$$$ and $$$y = W + y_0 \gt q$$$,
If $$$p & q = 0$$$, then binary addition has no carry, hence
Therefore
Now define
Since $$$q'$$$ is the bitwise complement of $$$x_0$$$ on the lower $$$n-1$$$ bits,
The cost is
Since $$$W \ge 1$$$,
Thus the $$$(0,0)$$$ case cannot be optimal.
Lemma 3
Fix $$$(p_1,q_1) = (1,0)$$$. Then there exists an optimal solution with $$$p = x$$$.
Proof
Write $$$p = W + p_0$$$, $$$q = q_0$$$. The cost is
For fixed $$$p_0$$$, this is minimized by maximizing $$$q_0$$$ subject to $$$p_0 \& q_0 = 0$$$, i.e.
The resulting cost is
Define $$$g(t) = t + |x_0 - t|$$$. Then
Hence the minimum is attained at $$$t = x_0$$$, yielding $$$p = x$$$.
By symmetry, in the $$$(0,1)$$$ case there exists an optimal solution with $$$q = y$$$.
Conclusion
In all cases, there exists an optimal solution $$$(p,q)$$$ satisfying
Equivalently,
Proofs of the intended solution are similar with this.
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
i64 x, y;
std::cin >> x >> y;
i64 min = 1e18, p, q;
auto upd = [&](i64 _p, i64 _q) -> void {
if ((_p & _q) == 0 && abs(_p - x) + abs(_q - y) < min) {
min = abs(_p - x) + abs(_q - y);
p = _p;
q = _q;
}
};
upd(x, y);
for (int i = 29; i >= 0; i--) {
if ((x & y) >> i & 1) {
upd((x >> i << i) + (1LL << i), y);
upd(x, (y >> i << i) + (1LL << i));
upd(x >> i << i, (y >> i << i) - 1);
upd((x >> i << i) - 1, y >> i << i);
}
}
std::cout << p << " " << q << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
}
Idea: Bronya_H, __baozii__
Solution: __baozii__
Editorial: __baozii__
What is the optimal strategy for both players?
If you have obtained a formula for $$$f(x,y)$$$, how do you calculate the required sum efficiently, perhaps using some tree techniques?
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
i64 solve_tree(int n, int r, vector<vector<int>> g) {
vector<int> dep(n), sz(n, 1), pa(n);
i64 ans = 0;
auto dfs = [&](auto &&self, int u, int p) -> map<int, int> {
pa[u] = p;
map<int, int> mp;
mp[dep[u]] = 1;
for (auto v : g[u]) if (v != p) {
dep[v] = dep[u] + 1;
auto nmp = self(self, v, u);
if (mp.size() < nmp.size()) swap(mp, nmp);
for (auto &[d, f] : nmp) {
ans += 1LL * f * mp[d] * (d - dep[u]);
mp[d] += f;
}
sz[u] += sz[v];
}
return mp;
};
dfs(dfs, r, -1);
for (int u = 0; u < n; u++) {
i64 s = 1LL * sz[u] * (sz[u] - 1) / 2;
for (auto v : g[u]) if (v != pa[u]) s -= 1LL * sz[v] * (sz[v] - 1) / 2;
ans -= 1LL * dep[u] * s;
}
sort(dep.begin(), dep.end());
for (int u = 0; u < n; u++) ans += 1LL * dep[u] * (n - u - 1);
return ans;
}
void solve() {
int n, m;
cin >> n >> m;
vector<int> a(n);
for (int i = 0; i < n - 1; i++) a[i] = i + 1;
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
u--;
v--;
a[u] = max(a[u], v);
}
vector<vector<int>> g(n);
for (int i = 0; i < n - 1; i++) g[a[i]].push_back(i);
cout << solve_tree(n, n - 1, g) << "\n";
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--) solve();
}
Solve the problem in $$$O(n)$$$.
Idea: Error_Yuan
Solution: Error_Yuan
Editorial: Error_Yuan
#include <bits/stdc++.h>
using namespace std;
using B = bitset<100001>;
using i64 = long long;
using i128 = __int128_t;
constexpr i64 MOD = 998244353;
vector<i64> calc(int n, string &s, i64 x, i64 y) {
B bf0, bf1, br0, br1;
bf0.set(0);
br0.set(0);
for (auto c : s) {
B nbf0, nbf1, nbr0, nbr1;
if (c != '1') {
nbf0 |= bf0 << 1;
nbf1 |= bf1 << 1;
nbr0 |= br0 >> 1;
nbr1 |= br1 >> 1;
}
if (c != '0') {
nbf0 |= br1;
nbf1 |= br0;
nbr0 |= bf1;
nbr1 |= bf0;
}
nbf0[0] = nbf0[0] | nbr0[0];
nbr0[0] = nbr0[0] | nbf0[0];
nbf1[0] = nbf1[0] | nbr1[0];
nbr1[0] = nbr1[0] | nbf1[0];
bf0 = nbf0;
bf1 = nbf1;
br0 = nbr0;
br1 = nbr1;
}
vector<i64> res;
auto tosum = [&](i64 c) -> i64 {
return (i128(c) * c + i128(x - y) * c + i128(n) * x * y) / (2 * x);
};
for (int i = 0; i <= n; i++) {
if (bf0[i]) res.push_back(tosum(i * x));
if (bf1[i]) res.push_back(tosum(i * x + y));
}
for (int i = 1; i <= n; i++) {
if (br0[i]) res.push_back(tosum(-i * x));
if (br1[i]) res.push_back(tosum(-i * x + y));
}
sort(res.begin(), res.end());
res.erase(unique(res.begin(), res.end()), res.end());
return res;
}
void solve() {
int n;
cin >> n;
i64 x, y;
cin >> x >> y;
string s;
cin >> s;
auto rs = calc(n, s, x, y);
i64 ans = 0;
for (auto v : rs) ans = (ans + (v % MOD + MOD)) % MOD;
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--) solve();
}
Idea: StarSilk
Solution: StarSilk
Editorial: __baozii__
Can you transform some constraints of the problem into something easier to handle?
Try to come up with a dynamic programming solution that runs in polynomial time.
How do you optimize your solution? Pay attention to any unusual constraints.
for _ in range(int(input())):
n = int(input())
a = list(map(int, input().split()))
s = input()
f = [10 ** 9] * 320
f[0] = 0
for i in range(n):
if s[i] == "1":
for j in range(318, -1, -1):
f[j + 1] = min(f[j + 1], f[j])
nf = [10 ** 9] * 320
for j in range(320):
nf[j] = min(nf[j], max(f[j], a[i]) + max(1, 2 * j - 1))
if j:
nf[j - 1] = min(nf[j - 1], f[j] + 2 * j - 1)
print(nf[0])
f = nf
Solve the problem in $$$O(n \operatorname{polylog} n)$$$.
2187F1 - Al Fine (Maximizing Version)
Processing two permutations is difficult. How can we reduce them to one?
To simplify the problem, we can relabel the vertices such that one of the DFS orders becomes the identity permutation $$$[0,1,2,\dots,n]$$$.
Specifically, let $$$mp[v]$$$ be the index of vertex $$$v$$$ in Arietta's DFS order $$$b$$$. We then transform Tortinita's DFS order $$$a$$$ into a new sequence $$$c$$$, where $$$c_i = mp[a_i]$$$. After this transformation:
- Arietta's sequence is effectively normalized to $$$0, 1, 2, \dots, n$$$.
- Tortinita's sequence $$$c$$$ now represents the relative positions of her nodes in Arietta's tree.
This reduces the problem from handling two arbitrary permutations to analyzing a single permutation $$$c$$$ relative to the natural order.
In a DFS order, the nodes of any subtree form a contiguous segment, with the root of the subtree appearing at the very beginning of that segment. What property does this imply for our problem?
After relabeling, any subtree in Arietta's tree not only forms a contiguous segment in terms of positions but also in terms of values (i.e., the set of values will be $$$[L, L+1, \dots, R]$$$).
This implies that for a common subtree to exist, if a segment $$$[L, L+1, \dots, R]$$$ represents a subtree in Arietta's tree, there must exist a corresponding segment in Tortinita's DFS order $$$c$$$ such that:
- The first element of the segment is $$$l$$$.
- The remaining $$$r-l$$$ elements are a permutation of the set $$${L+1, L+2, \dots, R}$$$.
The property that a segment must be a "permutation of a specific set" is not straightforward to check directly. Is there a way to simplify this condition into something more computationally efficient?
We can simplify this condition by leveraging the relationship between the maximum, minimum, and the length of the segment.
For a subsegment of $$$c$$$ starting at index $$$l$$$ and ending at index $$$r$$$ (i.e., $$$c[l \dots r]$$$), it represents a common subtree if and only if:
- $$$c[l] = \min(c[l \dots r])$$$: The first element must be the minimum value in the segment (acting as the root).
- $$$\max(c[l \dots r]) - \min(c[l \dots r]) = r - l$$$: The range of values is exactly equal to the number of edges, meaning the values are consecutive.
Because each valid segment can be mapped to a subtree, the valid segments form a laminar family (i.e., they do not cross). Any two valid segments are either completely disjoint or one is strictly contained inside the other.
The problem asks for the largest depth. To achieve this, we can greedily find the largest valid segment for every fixed start position.
Read the hints above.
Recall that we need to solve for any $$$1 \le l \le n$$$, the largest $$$r$$$ such that:
- $$$c[l] = \min(c[l \dots r])$$$
- $$$\max(c[l \dots r]) - \min(c[l \dots r]) = r - l$$$
There are multiple ways to solve this. We will introduce a divide-and-conquer approach.
To solve this problem using a divide-and-conquer approach, we define a recursive function that processes the interval $$$[l, r]$$$. The core logic handles the sub-problems where the valid range $$$[i, j]$$$ crosses the midpoint $$$mid$$$ (with $$$l \le i \le mid \lt j \le r$$$).
We precompute the prefix minimums and maximums for the right half ($$$mid + 1 \dots r$$$) and the suffix minimums and maximums for the left half ($$$l \dots mid$$$). Let's denote the suffix values for index $$$i$$$ as $$$min[i]$$$ and $$$max[i]$$$, and similarly for the prefix values at index $$$j$$$.
The problem requires $$$c[i] = \min(c[i \dots j])$$$. Since we are iterating $$$i$$$ from $$$mid$$$ down to $$$l$$$, this condition implies that $$$c[i]$$$ must be the minimum of the left part $$$c[i \dots mid]$$$. If $$$min[i] \neq min[i+1]$$$, it indicates that $$$c[i]$$$ is strictly smaller than the minimum of the range to its right, making it a candidate for the global minimum.
For such valid $$$i$$$, we consider two cases based on the location of the maximum value in the range $$$[i, j]$$$:
Case 1: The Maximum is on the Left
If the maximum value of the range is determined by the left side (i.e., $$$\max(c[i \dots j]) = max[i]$$$), the equation $$$\max - \min = j - i$$$ can be rewritten to determine the specific target index $$$j$$$:
We simply calculate this candidate $$$j$$$ and verify three conditions:
- $$$j$$$ is within the valid right range ($$$mid \lt j \le r$$$).
- The minimum on the right does not contradict our global minimum assumption ($$$min[j] \gt min[i]$$$).
- The maximum on the right is not larger than our current maximum ($$$max[j] \lt max[i]$$$).
If these hold, we update the answer for $$$i$$$.
Case 2: The Maximum is on the Right
If the maximum value is on the right side (i.e., $$$\max(c[i \dots j]) = max[j]$$$), the equation becomes:
Rearranging the terms to separate $$$i$$$ and $$$j$$$, we get:
To solve this efficiently, we group the indices $$$j$$$ from the right half based on the value of $$$max[j] - j$$$. For each $$$i$$$, we simply access the corresponding group to find the largest $$$j$$$ that satisfies the remaining validity conditions ($$$min[j] \gt min[i]$$$ and $$$max[j] \gt max[i]$$$). Because $$$max[j]$$$ is monotonic, we can introduce two-pointer strategy to avoid the $$$\log$$$ factor.
By conducting this algorithm, we can solve the largest valid segments for each start position. Then, we can use a stack to simulate the dfs process of the common tree, and solve the maximum depth easily.
The time complexity is $$$O(n\log n)$$$ by careful implementation.
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n+1), b(n+1);
for (int i = 1; i <= n; ++i) std::cin >> a[i];
for (int i = 1; i <= n; ++i) std::cin >> b[i];
std::vector<int> mp(n+1), c(n+1), R(n+1);
for (int i = 1; i <= n; ++i) mp[b[i]] = i;
for (int i = 1; i <= n; ++i) c[i] = mp[a[i]];
for (int i = 1; i <= n; ++i) mp[c[i]] = i;
std::vector<int> min(n + 1), max(n + 1);
std::vector<std::vector<std::pair<int, int>>> rmax(2 * n + 1);
std::vector<int> p(2 * n + 1);
auto work = [&](auto &&self, int l, int r) -> void {
if (l >= r) return;
int mid = l + (r - l) / 2;
self(self, l, mid);
self(self, mid + 1, r);
min[mid] = max[mid] = c[mid];
for (int i = mid - 1; i >= l; --i) {
min[i] = std::min(min[i + 1], c[i]);
max[i] = std::max(max[i + 1], c[i]);
}
min[mid + 1] = max[mid + 1] = c[mid + 1];
rmax[c[mid + 1] - mid - 1 + n].emplace_back(c[mid + 1], mid + 1);
for (int i = mid + 2; i <= r; ++i) {
min[i] = std::min(min[i - 1], c[i]);
max[i] = std::max(max[i - 1], c[i]);
rmax[max[i] - i + n].emplace_back(min[i], i);
}
for (int i = mid; i >= l; --i) {
if (min[i] != min[i + 1]) {
int j = i + max[i] - min[i];
if (j > mid && j <= r && min[j] > min[i] && max[j] < max[i]) {
R[i] = std::max(R[i], j);
}
j = min[i] - i + n;
while (p[j] < std::ssize(rmax[j]) && rmax[j][p[j]].first > min[i]) {
++p[j];
}
if (p[j]) {
int k = rmax[j][p[j] - 1].second;
if (max[k] > max[i]) R[i] = std::max(R[i], k);
}
}
}
for (int i = mid + 1; i <= r; ++i) {
rmax[max[i] - i + n].clear();
p[max[i] - i + n] = 0;
}
};
work(work, 1, n);
std::stack<int> st;
int ans = 0;
for (int i = 1; i <= n; ++i) {
while (!st.empty() && st.top() <= i) st.pop();
if (R[i]) {
st.push(R[i]);
ans = std::max(ans, int(st.size()));
}
}
std::cout << (ans + 1) << '\n';
}
int main() {
std::cin.tie(nullptr)->sync_with_stdio(false);
int T = 1;
std::cin >> T;
while (T--) solve();
return 0;
}
The problem background is a tribute to the visual novel Symphonic Rain. I highly recommend you to play it!
2187F2 - Al Fine (Counting Version)
Construct the optimal tree by following the approach used in F1. Two child nodes $$$a$$$ and $$$b$$$ of a node are defined as entangled if and only if $$$a$$$ and $$$b$$$ appear in different orders in the two permutations. The maximal entangled set of a node's children is defined as the largest connected component formed by the entangled relationships among its children.
Theorem $$$1$$$: Each maximal entangled set and the points in its subtree must form an interval in both DFS sequences.
Proof: Suppose one DFS sequence contains nodes $$$a, b, c$$$ such that $$$a$$$ and $$$c$$$ belong to the same maximal entanglement set while $$$b$$$ does not. Then in the other DFS sequence, all nodes after $$$b$$$ must appear after $$$a$$$ and before $$$c$$$. Thus $$$a$$$ and $$$c$$$ cannot be entangled, leading to a contradiction.
Theorem $$$2$$$: Among the maximal entangled sets of a leaf node, if any maximal entangled set contains only one node, then this maximal entangled set must be the last maximal entangled set to appear in both DFS sequences.
Proof: Suppose there exists a maximal entanglement set with a single node that is not the latest maximal entanglement set in either DFS sequence. Then all subsequent maximal entanglement sets must be able to be connected under this node, contradicting the optimal tree property.
Theorem $$$3$$$: A maximal entanglement set must be connected under the same node in any valid tree.
Proof: For a pair of entangled child nodes $$$x, y$$$ of node $$$a$$$ in an optimal tree, let $$$p_x$$$ and $$$p_y$$$ be the ancestors of $$$x$$$ and $$$y$$$, respectively. Since $$$p_x$$$ and $$$p_y$$$ cannot be points in the subtree of $$$a$$$ other than $$$a$$$ itself (otherwise it contradicts the optimal tree structure). Furthermore, since $$$x$$$ appears earlier than $$$y$$$ in some DFS sequence, traversing from $$$x$$$ to $$$y$$$ requires popping all other nodes in $$$a$$$'s subtree (because $$$p_y$$$ is not within the maximal entangled group's range). This implies that traversing from $$$x$$$ to $$$y$$$ can only be achieved by popping $$$p_y$$$ multiple times from $$$x$$$ and then attaching $$$y$$$ to $$$p_y$$$. Thus, $$$p_y$$$ must be an ancestor of $$$p_x$$$. Similarly, $$$p_x$$$ must also be an ancestor of $$$p_y$$$, so $$$p_x = p_y$$$.
Theorem $$$4$$$: If a maximal entanglement set has size greater than 1, then on any valid tree, if the parent node of this maximal entanglement set is $$$p$$$, then the subtree of all nodes within this maximal entanglement set must lie within the subtree of $$$p$$$.
Proof: Suppose a node $$$d$$$ in the subtree of some node $$$x$$$ within the maximal entanglement set does not lie within the subtree of $$$p$$$. Find a node $$$y$$$ entangled with $$$x$$$. Then, in the DFS sequence where $$$x$$$ appears before $$$y$$$, $$$d$$$ must lie between $$$x$$$ and $$$y$$$, contradicting that $$$d$$$ is not in the subtree of $$$p$$$.
Therefore, each maximal entanglement set greater than $$$1$$$ can be collapsed into a single node, treated as a leaf attached to its parent. At this point, the two DFS sequences become identical. The number of solutions is thus equal to the number of trees where the DFS sequences perfectly match and every node that was originally in a maximal entanglement set remains a leaf in the new tree. For solutions within each maximal entanglement set, we can recursively compute the number of trees matching the DFS sequence for each node within that set. Multiplying these values yields the total number of valid trees.
Consider counting the number of trees where the DFS sequence is identical to the given sequence, and every node that was originally in a maximal entanglement set remains a leaf in the new tree. Treat the DFS process as a bracket sequence: entering a new node is treated as a left bracket, and exiting a node is treated as a right bracket. If a node is a leaf, then the next bracket after its left bracket must be a right bracket. Thus, the problem asks for the number of bracket sequences that satisfy having $$$n$$$ left brackets and right brackets, where the next bracket after the $$$a_1, a_2, \dots, a_m$$$th left bracket is always a right bracket. A simple $$$O(n^2)$$$ dynamic programming approach suffices to find the answer.
The overall time complexity is $$$O(n^2)$$$.
#include<bits/stdc++.h>
using namespace std;
const long long mod=1000000007;
long long ans;
int a[5000],b[5000],pa[5000],pb[5000],tvis[5000],cvis[5000],zvis[5000];
vector<int>line[5001];
int dep[5001],cntsg[5001],wp[5001];
vector<int>vec;
long long dp[5001],tdp[5001];
long long solve(){
long long i,j,n=vec.size(),csum;
for(i=0;i<=n;i++)dp[i]=0;
dp[0]=1;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)tdp[j+vec[i]]=(tdp[j+vec[i]]+dp[j])%mod;
csum=0;
for(j=n;j>=0;j--)
{
csum=(csum+tdp[j])%mod;
dp[j]=csum;
tdp[j]=0;
}
}
vec.clear();
return dp[0];
}
void dfs(int t){
vector<int>::iterator it;
int i;
for(i=0;i<cntsg[t];i++)vec.push_back(0);
if(wp[t]==-1)ans=ans*solve()%mod;
else
{
vec.push_back(1);
dfs(wp[t]);
}
for(it=line[t].begin();it!=line[t].end();it++)
{
if(*it==wp[t])continue;
vec.push_back(1);
dfs(*it);
}
}
int main(){
ios::sync_with_stdio(false),cin.tie(0);
int T,n,i,j,t,ccnt,r;
for(cin>>T;T>0;T--)
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
a[i]--;
pa[a[i]]=i;
}
for(i=0;i<n;i++)
{
cin>>b[i];
b[i]--;
pb[b[i]]=i;
}
for(i=0;i<n;i++)tvis[i]=0;
for(i=n-1;i>-1;i--)
{
t=pb[a[i]];
cntsg[i]=0;
wp[i]=-1;
for(j=0;j<n;j++)
{
cvis[j]=0;
zvis[j]=0;
}
ccnt=0;
r=-1;
for(j=0;i+j<n&&t+j<n;j++)
{
if(cvis[a[i+j]]==0)ccnt++;
cvis[a[i+j]]++;
if(cvis[a[i+j]]==0)ccnt--;
if(cvis[b[t+j]]==0)ccnt++;
cvis[b[t+j]]--;
if(cvis[b[t+j]]==0)ccnt--;
if(ccnt==0)
{
zvis[i+j]=1;
r=i+j;
}
}
for(j=i+1;j<=r;j++)
{
if(tvis[j])
{
line[i].push_back(j);
tvis[j]=0;
if(zvis[j-1])
{
cntsg[i]++;
wp[i]=j;
}
else wp[i]=-1;
}
}
if(wp[i]!=-1)cntsg[i]--;
tvis[i]=1;
}
cntsg[n]=0;
wp[n]=-1;
for(i=0;i<n;i++)
{
cvis[i]=0;
zvis[i]=0;
}
ccnt=0;
r=-1;
for(i=0;i<n;i++)
{
if(cvis[a[i]]==0)ccnt++;
cvis[a[i]]++;
if(cvis[a[i]]==0)ccnt--;
if(cvis[b[i]]==0)ccnt++;
cvis[b[i]]--;
if(cvis[b[i]]==0)ccnt--;
if(ccnt==0)
{
zvis[i]=1;
r=i;
}
}
for(i=0;i<n;i++)
{
if(tvis[i])
{
line[n].push_back(i);
tvis[i]=0;
if(i==0||zvis[i-1])
{
cntsg[n]++;
wp[n]=i;
}
else wp[n]=-1;
}
}
if(wp[n]!=-1)cntsg[n]--;
ans=1;
dep[n]=0;
dfs(n);
for(i=0;i<=n;i++)line[i].clear();
cout<<ans<<'\n';
}
return 0;
}
Solve the problem in $$$O(n \log^2 n)$$$.
Observation 0: If $$$q_1,q_2,\dots,q_n$$$ is valid, then $$$q_1\bmod n+1,q_2\bmod n+1,\dots,q_n\bmod n+1$$$ is another valid $$$q$$$. This is obvious.
Therefore, we do not need the exact original labeling of values. We may assume $$$q_v=n$$$.
Define $$$Child_v={u\mid s[u][v]=1}$$$; Define $$$smn_v = min_{u\in Child_v}u$$$; Define $$$smx_v = max_{u\in Child_v}u$$$.
Observation 1: If the value at index $$$v$$$ is $$$n$$$, then the position of $$$n−1$$$ must be either $$$mn_v$$$ or $$$mx_v$$$.
Proof: If $$$q_{x}=n-1$$$, and $$$smn_v \lt x \lt smx_v$$$. Then the parent node of at least one of $$$mn_v$$$ and $$$mx_v$$$ must be $$$x$$$. This is contrary to the previous assumption.
So we only need to choose between these two candidates. We may assume $$$q_u=n-1$$$.
Define an edge $$$(u, parent_u)$$$ to cross index $$$v$$$ if $$$u$$$ and its parent lie on different sides of $$$v$$$, in other words, $$$(u-v)\cdot(parent_u-v) \lt 0$$$.
Observation 2: In every Cartesian tree during the process, the edge between index $$$u$$$ ($$$q_u=n-1$$$) and its parent $$$(u, parent_u)$$$ never cross the index $$$v$$$ ($$$q_v=n$$$).
Proof: For every node on a Cartesian tree, its parent node must be the closest node greater than it. If this edge $$$(u, parent_u)$$$ crosses node v, then one side's closest point to node u becomes v, leading to a contradiction.
Now let's decide whether $$$n−1$$$ is on the left or right. We are at index $$$v$$$ (treat it as value $$$n$$$).
Case A: all extreme children are on one side. If $$$smx_v \lt v$$$, then every child that ever attaches to $$$v$$$ lies left of $$$v$$$. Therefore $$$n−1$$$ must be on the left, and by Observation 1 it must be $$$smn_v$$$. If $$$smn_v \gt v$$$, similarly $$$n−1$$$ must be on the right, hence it must be $$$smx_v$$$.
Case B: children exist on both sides ($$$smn_v \lt v \lt smx_v$$$)
Observation 3: In the case B ($$$smn_v \lt v \lt smx_v$$$), among these two extreme children, one must have at least one parent edge crosses $$$v$$$, and the other one mustn't.
Proof: One child $$$q_x=n-1$$$ mustn't have a parent edge that crosses the index $$$v$$$ ($$$q_v=n$$$) due to the observation 2. For the other child node $$$q_y$$$, when $$$q_x=n-1$$$ is the root node, the parent node of $$$q_y$$$ must be $$$q_x$$$. They are on both sides of index $$$v$$$ ($$$q_v=n$$$). Therefore, it has at least one parent edge that crosses the index $$$v$$$ ($$$q_v=n$$$).
Similarly, define $$$Fa_v={u\mid s[v][u]=1}$$$; Define $$$fmn_v = min_{u\in Fa_v}u$$$; Define $$$fmx_v = max_{u\in Fa_v}u$$$.
If $$$fmx_{smn_v} \lt v$$$, then $$$smn_v$$$ doesn't have a parent edge that crosses $$$v$$$, then $$$q_{smn_v} = n - 1$$$. And vice versa.
The time complexity is $$$O(n^2)$$$. The bottleneck is preprocessing the input data.
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> fa_mx(n + 1), fa_mn(n + 1, n);
vector<int> son_mx(n + 1), son_mn(n + 1, n);
vector<vector<int>> fa(n + 1), son(n + 1);
for (int i = 1; i <= n; i++) {
string s;
cin >> s;
s = ' ' + s;
for (int j = 1; j <= n; j++) {
if (i == j or s[j] == '0') continue;
int u = j, v = i;
fa_mx[v] = max(fa_mx[v], u);
fa_mn[v] = min(fa_mn[v], u);
son_mx[u] = max(son_mx[u], v);
son_mn[u] = min(son_mn[u], v);
}
}
vector<int> a(n + 1);
for (int p = n, val = n; ; val--) {
a[p] = val;
if (val == 1) break;
int mn = son_mn[p], mx = son_mx[p];
if (mx < p) {
p = mn;
} else if (mn > p) {
p = mx;
} else {
int mx1 = fa_mx[mn];
if (mx1 <= p) {
p = mn;
} else {
int mn2 = fa_mn[mx];
assert(mn2 >= p);
p = mx;
}
}
}
for (int i = 1; i <= n; i++) {
cout << a[i] << " \n"[i == n];
}
}
}








Auto comment: topic has been updated by __baozii__ (previous revision, new revision, compare).
I liked C a lot! Didn't think much about D during contest, but it looks fun and challenging! Anyway, here's my take on problem C: link.
Greedy Construction solution for D2D/D1B : Solution Link
Thanks for the contest :)
Thanks for the contest and quick editorial!
Here's a braindead solution to Div1B where the correctness is completely obvious. It actually looks quite similar to the editorial solution and might end up producing the same output, but with a small sacrifice in runtime it becomes easier to prove.
Iterate over the $$$31^2$$$ possible combinations of the most significant bit you change in $$$x$$$ and $$$y$$$ (the extra 1 is from the possibility of not changing the value). If this changes a $$$0$$$ to a $$$1$$$ then the value increases, so we want to set all future bits to $$$0$$$ to increase it by as little as possible. Otherwise, if this changes a $$$1$$$ to a $$$0$$$ then the value decreases, so we want to set all future bits to $$$1$$$. However, if we are decreasing both values, this is invalid, so we will set the one with the earlier msb to all $$$1$$$s and the one with the later msb to all $$$0$$$s, thereby losing as little value as possible. Then, check if the resulting $$$p$$$ and $$$q$$$ satisfy the given condition and find the minimum over all satisfactory choices of msbs.
Submission: 360566950
Unfortunately I spent an hour doing some horrific casework before thinking of this, then I got nowhere on C, so I guess I'm back to CM for now, but I enjoyed the round nevertheless.
Edit: ok now that I think about it, the proof is not as trivial as I thought it was, since there are some tricky cases where the bits in between the two msbs are 1. There's an easy way to take care of this, though. If you fix the most significant bits you change, now you can greedily assign everything lower.
Can you elaborate a bit on your edit? I'm not sure what exactly changed since you're fixing the MSB and assigning lower bits in both the cases.
Something like, suppose i = position of msb you change in x, j = position of msb you change in y. WLOG, let i > j, that is, i is more significant than j. Maybe x = 6 and y = 3, for example. Furthermore, suppose that x_i = 1 and y_i = 0.
Then assigning
p = ...0111111
q = ...xxx1000
where x can be anything, won't necessarily be optimal because in particular, it's not always legal since the x's might be 1s. But you can just assign greedily where on each bit you ensure it's legal, and since you already fixed the msbs, it's easy to see how you want to greedily assign each value.
Anyways, even the original solution still ACs, it's just nontrivial to prove now; you have to show that all choices of i, j that cause this issue are suboptimal, which is probably true by some exchange argument. The greedy is fairly easy to prove, I think.
Can you prove the editorial for this problem? The claims they have made? If you can just explain the editorial to a newbie like me in a layman terms, I would appreciate it.
i basically did this i think, sooo painful
On problem D (div 2) "Shortest Statement Ever" the editorial said:
How to prove that?
It is a direct corollary of the intended solution. However some contestants and testers seemed to have guessed it.
Hi, thanks for the contest! Can you provide a proof for the intended solution? I can't figure out the details myself despite guessing it in the contest.
I don't understand the proof of Lemma 1. If $$$x = 011$$$ and $$$p = 100$$$, isn't it worse to subtract $$$W$$$ from $$$p$$$, which would result in $$$p' = 000$$$? $$$|x - p|$$$ is $$$1$$$ while $$$|x - p'|$$$ is $$$3$$$, right?
My Code I did my solution based on this observation which is O(1). Basically if q=y then you can ALWAYS make the lowerbits (starting from the highest same bit) of x to the complement of lower bits of y, by subtracting.
In div1D, I liked to think of it as, if $$$y = 0$$$ and $$$x = 1$$$, "our current sum is $$$0+1+\ldots+k$$$, and by default we are adding the next number/removing the last number". If we read
0from the string, we do what we are going to do by default,1changes this default option and applies the new default immediately. After that it's still the same knapsack etc, but it required me to handle the case where we want to remove the last number from "our current sum is $$$0$$$" separately, so it's not the cleanest way to describe the solution, but it's what I had in mind when solving this.In div1F1, I copy-pasted the PQ tree from yosupo judge, and then wrote some DP on it, but unlike normal tree DPs, this one required handling the siblings as well.
All in all, thanks for the contest! D was super cool
O(n) time complexity and O(1) space complexity solution for 2A: 360643885 — can likely be further optimized!
$$$O(1)$$$ time complexity for D2D/D1B: 360647850.
.
1E can be optimized to $$$O(n\log n)$$$ by FHQ Treap. Code: 360602874.
D is the worst problem I have ever seen.
us
The most difficult task was D, div.2
Div1 C cool problem
I feel like I could have easily solved div.2B and Div.2C but making an "M" on my graph was too tempting for the inner me
I think in editorial of Div2 D. the variables x y p q are different in the statement and editorial.
My (maybe overcomplicated) DP solution to div1 B / div2 D.
Let $$$x_i$$$ and $$$y_i$$$ be the $$$i$$$-th lowest bit of $$$x$$$ and $$$y$$$ $$$(0 \le x_i, y_i \le 1)$$$.
Let the DP state be $$$D[i, j, k] \; (0 \le i \le 31, -1 \le j, k \le 1)$$$. $$$i$$$ is the bit index (counting from the lowest). $$$j = 1$$$ means the value of $$$p$$$ has a carry in the digit $$$i$$$; $$$j = -1$$$ means $$$p$$$ has a borrow in the digit $$$i$$$; $$$j = 0$$$ means the otherwise. The same applies to $$$k$$$, for the value of $$$q$$$. $$$D[i, j, k]$$$ is the minimum deviation from $$$x$$$ and $$$y$$$ (i.e. the value of $$$\left| x-p \right| + \left| y-q \right|$$$) that's required to arrive at the state.
Initially, $$$D[0, 0, 0] = 0$$$ and $$$D[i, j, k] = \infty$$$ for the rest.
Let's think about the state transition from $$$D[i, j, k] \; (i \le 30)$$$. The current value of $$$p$$$ and $$$q$$$ at the bit $$$i$$$, including a carry or a borrow, is: $$$a = x_i + j$$$ and $$$b = y_i + k$$$ $$$(-1 \le a, b \le 2)$$$.
Let's bruteforce and consider all the combinations of changes to $$$p$$$ and $$$q$$$ at the bit $$$i$$$: you might want to add $$$1$$$ to or subtract $$$1$$$ from the $$$i$$$-th bit of $$$p$$$ and $$$q$$$. For all $$$-1 \le c \le 1$$$ and $$$-1 \le d \le 1$$$, the new $$$i$$$-th bit of $$$p$$$ and $$$q$$$ are: $$$a^\prime = a + c, \, b^\prime = b + d \; (-2 \le a^\prime, b^\prime \le 3)$$$. If $$$a^\prime \mathbin{\&} 1 = 1$$$ and $$$b^\prime \mathbin{\&} 1 = 1$$$, then these don't satisfy the problem condition, so skip. Otherwise, this change pattern can be viable. Note that the carry or the borrow of $$$a^\prime$$$ and $$$b^\prime$$$ affects the next bit only. The effect of the next bit can be denoted as: $$$\displaystyle j^\prime = \left\lfloor a^\prime / 2 \right\rfloor, \, k^\prime = \left\lfloor b^\prime / 2 \right\rfloor$$$. The cost of this change (the deviation from $$$x$$$ and $$$y$$$) can be calculated as: $$$\displaystyle s = \left( \left| c \right| + \left| d \right| \right) \cdot 2^i$$$. With that, update the DP state as follows:
After all the transitions, the minimum deviation from $$$x$$$ and $$$y$$$ can be obtained as $$$D[31, 0, 0]$$$. You can recover the value of $$$p$$$ and $$$q$$$ by backtracking the DP table, if you leave enough information as you make the transition.
I did the solution for Div2 D using the greedy where we fix one of x=p or y=q, and then change the bits of the other one greedily to get to the correct answer. Here is my submission: 360578329, this is getting WA at pretest 2, I have tried almost every testcase I can think of.
I did the same. Getting wa on test 2. Want to find out how it is failing
Yeah, I found a small error in my if else loop, but I even corrected it, still it is failing on some 1020 test, either it is some edge case that we are missing.
I made a mistake in problem B and used ceil(n/3) instead of floor(n/3)(( Good tasks! Thanks to the authors
you can use ceil function. my 360729884 submission uses it.
C,D are good problems, and I like them much. However, I think it's not suitable to have these four problems as ABCD in div2, since they require no algorithm(need the thought of greedy, maybe)
For div2D, abs(x-p) could be x-p, p-x, 0 depending on x > p, x < p, x = p maintain a DP with three states, bit position, state for p {whether, > < or =}, state for q there are three possibilities for bit assignment for p&q=0 at position j get the new state as bit is assigned and maintain current minimum as current state establishes the inequality to calculate abs(x-p) + abs(x-q), store the minimum reached for every such state and trace back to get values of p and q
Auto comment: topic has been updated by Tobo (previous revision, new revision, compare).
thanks for the problems was tired of mathforces!
Can someone please give a simple solution to Div2 D? Which makes sense like the editorial or comments here are just observations and not the actual proof. What does it take for the editor to also provide proof rather than saying left for readers? Bro, we can also observe it from others solutions and I also observed it on my own but couldn't prove or satisfy myself, so please someone either prove the editorial solution or give a valid simple proof to your solution rather than saying it can be proved or it can be observed. I'm a beginner but would appreciate a humble guy trying to help others than people showing off it can be proved, observed, that doesn't help at all. Please correct the editorial and add the proof. Humble request.
ok so as a pupil myself what i understood first simply by observation and casework that if i choose say my p as x then i can find a q which is the optimal solution this was done purely based on casework. Now once i fix say p=x now i want a q which is as close as possible to y so to minimize the sum so to do that i can only use those bits which are unset in x since we want p&q==0 so i crate a mask where those bits are set which are unset in x now we build our q first as close to y as possible to do this we would build two numbers l and h where l is the largest number closest to y and h be the smallest number greater than y how you build you can see my code it would be much more clear to you
but how can you assume only if you fix p = x (or vice versa) then it's optimal, because this is observation, but you can't prove what if p is also as close as possible to x and y is also as close as possible to y but none are exactly equal. Like we need a way to prove that it's always optimal if either p = x or q = y and any deviation will only increase the answer.
I solved it with DP as abs(x-p) could be x-p, p-x, 0 depending on x > p, x < p, x = p maintain a DP with three states, bit position, state for p {whether, > < or =}, state for q there are three possibilities for bit assignment for p&q=0 at position j get the new state as bit is assigned and maintain current minimum as current state establishes the inequality to calculate abs(x-p) + abs(x-q), store the minimum reached for every such state and trace back to get values of p and q. Why this works is because if you are already larger at a position j, you will always be larger later and if you are already smaller at a position j, you will be always smaller later. That solves it by saving to check all the permutations in 32*3*3*4.
I got dp solution but want greedy intuition
Auto comment: topic has been updated by __baozii__ (previous revision, new revision, compare).
div 2 c was really a good problem. using max and min of element to sort the whole array is a main observation .
Can anyone explain me why this code gives wrong answer on some test cases.
I sneaked problem D by running a brute force and found that the coefficient only depend on count of prefix xor = 1. Still don't understand why.
Any intuition behind div1.D? After reading the editorial it just blows my mind how one can come up with this in contest.
If $$$x$$$ must be $$$a$$$ or $$$b$$$, then $$$(x - a) \cdot (x - b) = 0$$$ must hold.
There is no need to rewrite the formula in this magical way. Instead of handling two separate "if" cases, we can pack both possibilities into a single, initially messy equation:
Expanding this gives us a much more useful form:
Now, the magic happens when you sum this up for all $$$i$$$. The $$$c^2$$$ telescoping terms in the middle cancel out, allowing you to isolate $$$\sum c_i$$$.
I hope this helps!
Yeah, thank you very much. I guess intuition was to try to join the 2 equations into one, and see what we can get from there. Very interesting problem.
Auto comment: topic has been updated by -firefly- (previous revision, new revision, compare).
you guys should really stop leaving proof to readers for exercise for those problems need more guessing than reasoning, it's not interesting at all.
Auto comment: topic has been updated by Tobo (previous revision, new revision, compare).
Auto comment: topic has been updated by Tobo (previous revision, new revision, compare).
Auto comment: topic has been updated by Tobo (previous revision, new revision, compare).
One of the solution for d2D/d1B mentions that p=x OR q = y might be possible I am able to understand it intutively but am unable to figure out the reason why it should be true.
Could someone help out with the proof for the same?
thanks a lot for the great problem div2E and the well explained editorial. I think that there is a little typo in the editorial, it should be a "+" instead of a "-" for the last part of the sum (when d(x) == d(y))
Everytime when I see "Proofs are left as an exercise for the reader" in the editorial:
Sorry, but I've spent enough time during the contest trying to solve the problem and came to read a full solution after giving up, not to have more questions than answers why certain properties hold :) Apart from that, I think there were interesting problems!
I’m trying to understand why the answer is 2 for the string "000000" in the problem 2188B – Seats. Could someone explain how that result is obtained?
010010
Start from second position, if you try with 3rd, so you will have to fill 1st too, so start from 2nd ps and leave 2 zeroe, do it and at the end check if you need to fill one more seat at the end at last position
thank you so much!
ignore
My approach for div2 problem D is to fix p = x and find the optimal q, and also fix q = y and find the optimal p. However, my solution keeps giving wrong answers, and I don’t know what’s wrong. Here is my code[submission:360724737]—I'd really appreciate it if someone could help me figure it out.
__baozii__ What is the name of the trick? They way I have solved this question is through dealing vertex all togather based on depths for each vertex(iterating over every subtree except the one with max depth). You may see the code 360582035
This is $$$O(n)$$$ if I'm not mistaken.
This is known as long path decomposition
Can we please forbid authors from writing such statements in the editorial? this is an editorial, not a cpp-to-english translation tool. i am tired of seeing such problem solutions. this is so harmful to the div2 community…
if you guys also solve question on leetcode then question B was quite similar with leetcode question "Can Place Flower (605)". A and C was straight forward question just find one simple logic and that's it. D was quite hard for me. i was only able to solve first 3 questions.
In Div2 F, "optimized to O($$$n^2$$$ / w) using bitset". n <= $$$10^5$$$, how can we optimise the solution. $$$n^2$$$ solution will not pass.
Div 1 C Jerry and Tom Bonus Version:
So if auxiliary tree is constructed, then we shall process the tree, and for each node $$$u$$$, maintain:
Construct Auxiliary Tree:
Sorry for overkilling it, but good exercise.
Does anyone have any solution different from the editorial for Div 2F/Div 1D ?
Yes, I have a $$$O(n \log^2 n)$$$ solution using Divide-and-Conquer NTT.
Upsolving I reduced to subset sum which has an $$$O(\frac{n\sqrt{n}}{w})$$$ solution. Interestingly, it looks like this is tied for the fastest solution, which I wasn't trying to go for. The idea is to represent $$$c_i$$$ in terms of sums of $$$z_i$$$ where $$$z_i$$$ is the xorsum of $$$s_1\oplus\cdots\oplus s_i$$$, then $$$f$$$ can be written in terms of just $$$\sum_i z_i$$$. Each chain of $$$0$$$/$$$1$$$ in $$$s$$$ after a $$$'?'$$$ can be represented as two possibilities based on the value of the $$$'?'$$$ which reduces to subset-sum.
Then why is your solution $$$O(\frac{n\sqrt{n}}{w})$$$? Any proof?
Check out Subset Sum speedup 1 from https://mirror.codeforces.com/blog/entry/98663
Thanks a lot.
If anyone wants a dp solution for div 2 D :Problem Link
Here is my code:{If explanation needed , ping me} .
For 2187C/2188E, won't it sometimes be optimal to pick a node that's not the farthest?
Consider the following graph:
3->8 6->9
(Note that 1->2, 2->3, 3->4, ..., 9-10 also exist).
Say Jerry is at 3 while Tom is at 6 and it's Tom's turn. Tom would actually benefit to go from 6 to 7 rather than 6 to 9, since it prevents Jerry from going to 8 (Tom would go there next move) and forces him to, for the rest of the game, move one step at a time. If Tom moved to 9, Jerry could have moved one step at a time and the game would have lasted longer. If Tom stayed, then Jerry could go to 8 and go on to actually win the game.
Let's continue the same graph and look at it from Jerry's perspective. This time, he is at 3 and Tom is at 9. If Jerry moves to 8, Tom could stay and then Jerry would lose next turn. But he can also move to 4, and Tom would stay stationary for 5 more moves for Jerry to catch up. Thus, it would be best for him to go slow.
This example serves as a counter-example right?
Note that there do not exist two directed edges (ui→vi) and (uj→vj) such that ui<uj<vi<vj.
Is there a reason why Div 1 B doesn't break after finding the first highest conflict?
The weightage of subtraction here is dependent too much on the highest first conflict. 2^n will always be more than 2^0 + 2^1 + ... 2^(n-1). So assigning this bit to either one of the number will change the answer from there or take one of the numbers a little bigger.
I solved it by guessing from all 4 options that can happen on the first MSB match.
I understand the 4 options but why does the loop continue after the msb being found for conflict.
It does not. Just terminate the loop on the first msb match. You don't need to go on.
thanks was confused why we would continue on the editorial
in restricted string, how If ai−mn≥k and mx−aj≥k, how max-aj will be >=k if its not the toher case aj-min <k
360866947
This is my submission for problem B which one can refer as it is kind of mix of dp and greedy as I try all possible ways when I am not sure of which bits need to be placed for some bit i.
If you have any doubts, Feel free to ask. I will try to clarify.
Auto comment: topic has been updated by Tobo (previous revision, new revision, compare).
Auto comment: topic has been updated by Tobo (previous revision, new revision, compare).
Auto comment: topic has been updated by Tobo (previous revision, new revision, compare).
Div2E, Got so close but yet so far. Very nice problem :D
FireFly __baozii__
Please correct me if I am wrong for problem div1C.
In editorial, for the third summation, there should not be x<y condition when d(x)=d(y) as tom would win for both cases when x<y || x>y. maybe a multiplication factor of 2 should be there outside the third term.
Edit:Nvm, got it.First two term includes that contribution already which is also clear by the way you are calculating the first two terms.Really good Problemset.
Did anyone solve problem D using the following observation?
Equivalently, there exists an optimal solution (p, q) such that p = x or q = y.
yes, I have seen a submission following this idea somewhere
link pls
A slightly different intuition for solving the d1D/d2F problem. If we consider the fixed string $$$r$$$, we can see that $$$c[i]$$$ contributes to the total sum $$$y$$$ with a coefficient equal to $$$0$$$ or $$$1$$$, with a coefficient of $$$0$$$ if the number of ones in the prefix $$$s$$$ is even and $$$1$$$ if it is odd (i.e., $$$xor$$$ of prefix $$$i$$$). If, after this observation, we consider by analogy what happens to the $$$x$$$'s on prefixes with different $$$xor$$$, we can see that as long as the number of ones on prefixes $$$i$$$ and $$$i + 1$$$ is the same, $$$c[i+1]$$$ contributes one $$$x$$$ more to the sum than $$$c[i]$$$. after we encounter another unit, this type of operation will reverse all our $$$x$$$'s and we will lose the last member of the arithmetic progression. For example, let it be equal to $$$k*x$$$, then as long as the prefixes' $$$xor$$$ values are equal, we will continue to lose $$$(k-1)*x$$$, $$$(k-2)*x$$$, and so on for the subsequent terms of the arithmetic progression, until we encounter a unit again, at which point we will continue the arithmetic progression, but only from the last term that was not subtracted. This means that the total sum of all $$$c[i]$$$ is $$$y$$$ multiplied by the number of prefixes with $$$xor = 1$$$ plus an arithmetic progression with a step of $$$x$$$ and a length equal to the difference between the number of prefixes with $$$xor = 0$$$ and $$$xor = 1$$$.
I apologize, this was translated using a translation tool.
Could anyone please explain where I am going wrong with this solution for Div1 D.
My code keeps failing
Between two question marks, the value of c at the position is a linear function of the value at the question mark. Therefore when summing over all the sequences we can substitute the average value of c at the question mark in the linear function.
But the average value at the question mark is (x+y)/2 because it can be either 0 or 1 for every possible preceding sequence. So we calculate the sequence as normal, replacing c with (x+y)/2 at every question mark, summing the obtained values of c, then multiplying by 2^(no. of question marks)
For (x+y)/2 you can use the modular inverse of 2
You are treating this question as if it asks to compute $$$\sum_{\text{completions}} f(s)$$$ when $$$\sum_{k \in { \text{values that } f(s) \text{ can take} }} k$$$ is being asked. They differ when two completions yield the same value of $$$f$$$.
Counter-example for your approach: $$$n$$$ = 2, $$$x$$$ = 1, $$$y$$$ = 2, $$$s$$$ = ??
List Completions are as follows:
00: $$$c_1$$$ = 1, $$$c_2$$$ = 2, $$$\Rightarrow$$$ $$$f$$$ = 1+2 = 3.
01: $$$c_1$$$ = 1, $$$c_2$$$ = 1, $$$\Rightarrow$$$ $$$f$$$ = 2.
10: $$$c_1$$$ = 2, $$$c_2$$$ = 3, $$$\Rightarrow$$$ $$$f$$$ = 5.
11: $$$c_1$$$ = 2, $$$c_2$$$ = 0, $$$\Rightarrow$$$ $$$f$$$ = 2.
Cool Integer list is then {2,3,5} and the required answer becomes 10. However, multiplying by $$$2^{\text{count of ?}}$$$, you implicitly count each completion, which forces you to count $$$f$$$ = 2 twice, creating a mismatch.
For 2A, an alternate solution can be like this: 1. The first element is always ceil(n/2). 2. For every next element, you can add/subtract index i of the prev_element to the prev element alternatively to get the whole permutation.
can somebody Prove to me why this:
Its complexity is O($$$n \cdot log^2 n)$$$).
In Div1C how do we prove that the game end in finite steps
https://mirror.codeforces.com/profile/rom228.js look at this person's decisions
For Div 1 C, for the last summation shouldn't you add this term
instead of subtracting it?
Another solution for A-Divisible Permutation (C++)
One array only!.
Construct the answer in reverse order.
Take: q = [n, 1, n-1, 2, n-2, 3, ...] Then the adjacent differences in q are: n-1, n-2, n-3, ..., 1
After reversing q, the difference at position i becomes exactly i, so |p[i] — p[i+1]| = i, which is divisible by i.
What is the intended solution for the bonus of Doors and Keys?