Alice deletes a 0, Bob deletes a 1. Which occurrence should each of them choose?
Deleting a 0 makes the string lexicographically larger. Does the position of that 0 matter?
After Alice's move, Bob sees one string and deletes a 1. What is his best move?
Deleting a 0 at an earlier position is always better for Alice. Indeed, compare deleting the 0s at positions $$$i \lt j$$$: the two results agree before position $$$i$$$, and at position $$$i$$$ the first result has 1 while the second still has 0. So Alice deletes the first 0.
After that, Bob wants to minimize the string. By the symmetric argument he deletes the first 1 of the remaining string, which is the first 1 of the original string, since deleting a 0 never changes the order of the 1s.
Hence the answer is the original string with its first 0 and its first 1 removed.
Complexity: $$$O(n)$$$ per test case.
#include <cstdio>
#include <cstring>
const int N = 105;
char str[N];
void solve() {
scanf("%s", str + 1);
int n = strlen(str + 1);
bool c0 = 0, c1 = 0;
for (int i = 1; i <= n; i++) {
if (!c0 && str[i] == '0') {
c0 = true;
continue;
}
if (!c1 && str[i] == '1') {
c1 = true;
continue;
}
putchar(str[i]);
}
puts("");
}
int main() {
int t = 0;
scanf("%d", &t);
while (t--) solve();
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define nline "\n"
#define sz(x) (int)x.size()
void solve(){
string s; cin>>s;
string ans;
for(int i=0;i<sz(s);i++){
if(s[i]=='1'){
continue;
}
string t=s;
t.erase(t.begin()+i);
string cur;
for(int j=0;j<sz(t);j++){
if(t[j]=='0'){
continue;
}
string now=t;
now.erase(now.begin()+j);
if((cur.empty()) or (now<cur)){
cur=now;
}
}
if((ans.empty()) or (ans<cur)){
ans=cur;
}
}
cout<<ans<<nline;
return;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
ll test_cases=1;
cin>>test_cases;
while(test_cases--){
solve();
}
}
Sort both arrays. Each operation reduces the number of elements by exactly one.
All values are distinct, so no final element can be an untouched original element. What lower bound on $$$n$$$ does this give?
After sorting, in which interval of $$$a$$$ must the $$$i$$$-th smallest value $$$b_i$$$ lie?
Sort both arrays. An operation merges two elements $$$x \le y$$$ into any $$$z \in [x,y]$$$, so think of each final element as the merge of a group of original elements whose min/max bracket its value.
Necessity.
- $$$n \ge 2m$$$. The values in $$$b$$$ are distinct from those in $$$a$$$, so a final element consisting of a single original element is impossible. Every final element needs at least two originals.
- $$$a_i \le b_i \le a_{n-m+i}$$$. The $$$i$$$ smallest final values are produced by $$$i$$$ groups containing at least $$$i$$$ original elements, all $$$\le b_i$$$. Only $$$i-1$$$ original elements are smaller than $$$a_i$$$, so $$$b_i \ge a_i$$$. The symmetric argument on the largest values gives $$$b_i \le a_{n-m+i}$$$.
Sufficiency. If the conditions hold, pair $$$a_i$$$ with $$$a_{n-m+i}$$$ for each $$$i$$$ (the pairs are disjoint since $$$n \ge 2m$$$) and merge each pair into $$$b_i$$$. The remaining middle elements can be attached to any group one by one: merging the current group value $$$b_1$$$ with an extra element $$$e$$$ yields $$$b_1$$$ again, because $$$b_1$$$ lies between them.
Complexity: $$$O((n+m)\log(n+m))$$$ per test case.
using namespace std;
int main() {
int T;
scanf("%d", &T);
for (int _ = 0; _ < T; ++_) {
int n, m;
scanf("%d %d", &n, &m);
vector<int> a(n), b(m);
for (int &x : a) {
scanf("%d", &x);
}
for (int &x : b) {
scanf("%d", &x);
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
if (n < 2 * m) {
puts("NO");
continue;
}
int i = 0;
while (i < m && a[i] < b[i] && b[i] < a[n - m + i]) ++i;
puts(i < m ? "no" : "Yes");
}
return 0;
}
If a value is chosen when some elements between its two occurrences were already deleted, move its deletion earlier. When is this never worse? Think about $$$(a+b)^2 \ge a^2 + b^2$$$.
Conclude that the process is equivalent to partitioning the array into disjoint blocks: each block is either a single position, or the whole interval between two equal values at its ends.
DP over the prefix. Consider the block containing the last position.
Call an operation full if it deletes the entire original interval between the two occurrences of the chosen value.
Lemma. There is an optimal strategy in which every operation is full.
Suppose a value is chosen with current span $$$p \dots q$$$, while an interval $$$J$$$ strictly inside its original span was deleted earlier. Swap the two deletions: the value now covers the whole original interval. If the two original lengths are $$$A$$$ and $$$B$$$ ($$$A \ge B$$$), the score changes from at most $$$(A-B)^2 + B^2$$$ to $$$A^2$$$, and $$$(A-B)^2 + B^2 \le A^2$$$. So the total never decreases, and repeating this exchange makes every operation full.
Now the deleted intervals are disjoint, and the whole process is exactly: partition the array into blocks, each being a single position or the interval between the two equal values at its ends, and collect $$$\sum (\text{block length})^2$$$.
Let $$$dp[i]$$$ be the best score for the prefix $$$a_1 \dots a_i$$$. The block containing position $$$i$$$ is either the singleton $$${i}$$$, or the interval $$$[l,i]$$$ where $$$l$$$ is the first occurrence of $$$a_i$$$:
The singleton option never overestimates: if the mate of $$$a_i$$$ is still present in the optimal strategy of the prefix, deleting $$$[l,i]$$$ instead is at least as good, since $$$(i-l+1)^2 \ge (i-l)^2 + 1$$$.
The answer is $$$dp[2n]$$$.
Complexity: $$$O(n)$$$ per test case.
#include <bits/stdc++.h>
using namespace std;
int main() {
int T;
scanf("%d", &T);
for (int _ = 0; _ < T; ++_) {
int n;
scanf("%d", &n);
vector<int> a(2 * n);
for (int &x : a) {
scanf("%d", &x);
}
vector<int> lp(2 * n, -1);
vector<int> occ(n, -1);
for (int i = 0; i < 2 * n; ++i) {
if (occ[a[i] - 1] != -1) {
lp[i] = occ[a[i] - 1];
} else {
occ[a[i] - 1] = i;
}
}
vector<long long> dp(2 * n);
dp[0] = 1;
for (int i = 1; i < 2 * n; ++i) {
dp[i] = dp[i - 1] + 1;
if (lp[i] != -1) {
dp[i] = max(dp[i], (lp[i] == 0 ? 0 : dp[lp[i] - 1]) + 1LL * (i - lp[i] + 1) * (i - lp[i] + 1));
}
}
printf("%lld\n", dp[2 * n - 1]);
}
}
Classify each position by the pair $$$(s_i, t_i)$$$ and count the four types: $$$(0,0)$$$, $$$(0,1)$$$, $$$(1,0)$$$, $$$(1,1)$$$.
Find a quantity that only decreases during the game, and equals $$$0$$$ at the end.
Which pairs of columns can be deleted together in one operation? When can all columns be paired up?
For a substring pair let $$$x=N(0,1)$$$, $$$y=N(1,0)$$$, $$$u=N(0,0)$$$, $$$v=N(1,1)$$$, where $$$N(0,1)$$$ denotes the number occurrences of $$$(0,1)$$$.
Claim. The pair is good iff $$$|x-y| \le u+v$$$.
Necessity: Take any allowed operation. Let the deleted columns have counts $$$u_0, v_0, x_0, y_0$$$ and total $$$k = u_0+v_0+x_0+y_0$$$.
Case $$$c=0$$$:
In the deleted subsequence of $$$s$$$, character $$$0$$$ appears $$$u_0+x_0$$$ times; in $$$t$$$ it appears $$$u_0+y_0$$$ times.
Mode condition:
Adding them: $$$2u_0 + x_0 + y_0 \ge k = u_0+v_0+x_0+y_0$$$ $$$\Rightarrow$$$ $$$u_0 \ge v_0$$$.
Subtracting one from the other gives $$$|x_0 - y_0| \le u_0 - v_0 \le u_0 + v_0$$$.
Case $$$c=1$$$: similarly $$$v_0 \ge u_0$$$ and $$$|x_0 - y_0| \le v_0 - u_0 \le u_0 + v_0$$$.
Thus every operation satisfies $$$|x_0 - y_0| \le u_0+v_0$$$.
Now define the potential $$$\Phi = |x-y| - (u+v)$$$.
After one operation the change is
By the triangle inequality, $$$|x-y| - |(x-y)-(x_0-y_0)| \le |x_0-y_0|$$$.
Therefore
So $$$\Phi$$$ never decreases.
The empty pair has $$$\Phi = 0$$$. Hence initially $$$\Phi \le 0$$$, i.e. $$$|x-y| \le u+v$$$.
Sufficiency: We can empty the strings by repeatedly deleting columns in groups of size 1 or 2.
A single column can be deleted alone iff it is pure: $$$(0,0)$$$ (mode $$$0$$$) or $$$(1,1)$$$ (mode $$$1$$$). Two columns can be deleted together iff they are not two identical mixed columns:
$$$(0,0)$$$ pairs with anything.
$$$(1,1)$$$ pairs with anything.
$$$(0,1)$$$ pairs with $$$(1,0)$$$.
So we can pair $$$\min(x,y)$$$ copies of $$$(0,1)$$$ with $$$(1,0)$$$, and the remaining $$$|x-y|$$$ mixed columns (all of the same type) are paired with pure columns $$$(0,0)$$$ or $$$(1,1)$$$. This is possible exactly because $$$u+v \ge |x-y|$$$.
The leftover $$$u+v-|x-y|$$$ pure columns are paired arbitrarily among themselves. If the total number of columns is odd, exactly one pure column remains and can be deleted alone.
All these pairs / singletons are valid operations. After their deletion the strings become empty, so the pair is good.
Precompute prefix sums for the four column types. For a query $$$[l,r]$$$ obtain the four counts $$$u,v,x,y$$$ in constant time. Answer yes if $$$|x-y| \le u+v$$$, otherwise no.
Complexity: $$$O(n+q)$$$ per test case.
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <iostream>
#include <queue>
typedef long long LL;
using namespace std;
inline int read() {
int num = 0 ,f = 1; char c = getchar();
while (!isdigit(c)) f = c == '-' ? -1 : f ,c = getchar();
while (isdigit(c)) num = (num << 1) + (num << 3) + (c ^ 48) ,c = getchar();
return num * f;
}
const int N = 2e5 + 5;
char s[N] ,t[N];
int sum[4][N] ,n ,q;
inline void fuling_solve() {
n = read() ,q = read();
scanf("%s%s" ,s + 1 ,t + 1);
for (int j = 0; j < 4; j++) sum[j][0] = 0;
for (int i = 1; i <= n; i++) {
int id = (s[i] ^ 48) * 2 + (t[i] ^ 48);
for (int j = 0; j < 4; j++) sum[j][i] = sum[j][i - 1] + (id == j);
}
while (q--) {
int l = read() ,r = read();
int a = sum[0][r] - sum[0][l - 1];
int b = sum[1][r] - sum[1][l - 1];
int c = sum[2][r] - sum[2][l - 1];
int d = sum[3][r] - sum[3][l - 1];
puts(abs(b - c) <= a + d ? "YES" : "NO");
}
}
signed main() {
int t = read();
while (t--) fuling_solve();
return 0;
}
We have consider to change this problem to a harder version: Find number of pairs $$$(l, r) (1 \le l \le r \le n)$$$ such that $$$(s[l, r], t[l, r])$$$ is good.
Can you solve this too?
Let $$$S_i = F(I(i))$$$. Since the counter resets at $$$n$$$, $$$S_{i+n} = S_i + S_n$$$.
If $$$S_x + S_y \gt S_{x+y+1}$$$ for some $$$x,y$$$, the array $$$I(x),[0],I(y)$$$ already wins. Conversely, if no such pair exists, every array loses.
For fixed $$$y$$$, the function $$$S_x + S_y - S_{x+y+1}$$$ changes only when $$$x+1$$$ or $$$x+y+2$$$ is a reward point. Where is its maximum attained?
Let $$$S_i = F(I(i))$$$ ($$$S_0 = 0$$$). The counter resets exactly at $$$n$$$, so $$$S_{i+n} = S_i + S_n$$$; also $$$F$$$ is additive across a 0: if a string ends with 0, the next part starts from $$$c=0$$$.
Define
Claim. $$$F(s) \le S_{|s|} + \max(M,0)$$$ for every binary array $$$s$$$, with equality for $$$s = I(x),[0],I(y)$$$ at a maximizing pair. Hence the answer is YES iff $$$M \gt 0$$$.
Induct on the number of runs. If $$$s$$$ has no 0, then $$$F(s) = S_{|s|}$$$. Otherwise write $$$s = I(x),[0],t$$$ with $$$x$$$ leading ones. Then
because $$$S_x + S_{|t|} - S_{x+|t|+1} \le M$$$.
Only reward thresholds matter. Let $$$g(x,y) = S_x + S_y - S_{x+y+1}$$$. By periodicity $$$g$$$ is $$$n$$$-periodic in each variable. Fix $$$y$$$:
which is positive only when $$$x+1$$$ is a reward point $$$p_i$$$. On the circle of residues modulo $$$n$$$, the maximum is attained on a plateau whose left end is congruent to some $$$p_i$$$ — so some $$$x = p_i$$$ attains it. The same argument in $$$y$$$ gives
(If $$$m=0$$$, then $$$S_x = dx$$$ and $$$M = -d \le 0$$$.)
Algorithm. All needed values of $$$S$$$ follow from the periodic formula $$$S_i = \lfloor i/n\rfloor S_n + S_{i\bmod n}$$$. For each pair $$$(i,j)$$$, locate $$$p_i+p_j+1$$$ among the sorted points $$${p_1,\dots,p_m, n+p_1,\dots,n+p_m}$$$ with a two-pointer scan; if $$$S_{p_i}+S_{p_j} \gt S_{p_i+p_j+1}$$$ for some pair, print YES.
Complexity: $$$O(m^2)$$$ per test case ($$$\sum m \le 2000$$$).
import sys
input = sys.stdin.readline
class Point:
def __init__(self, t, v):
self.t = t
self.v = v
srw = [Point(0, 0) for _ in range(4100)]
T = int(input())
for _ in range(T):
n, m, d = map(int, input().split())
for i in range(1, m+1):
t, v = map(int, input().split())
srw[i].t = t
srw[i].v = v + srw[i-1].v
for i in range(1, m+1):
srw[m+i] = Point(n + srw[i].t, srw[m].v + srw[i].v)
ok = False
for i in range(1, m+1):
k = i
for j in range(1, m+1):
st = srw[i].t + 1 + srw[j].t
while k+1 <= 2*m and srw[k+1].t <= st:
k += 1
if srw[i].v + srw[i].t*d + srw[j].v + srw[j].t*d > srw[k].v + st*d:
ok = True
print("Yes" if ok else "No")
for i in range(1, 2*m+1):
srw[i] = Point(0, 0)
Define the deficit $$$g_{x,y} = \text{rowSum}_x + \text{colSum}_y - 3v_{x,y}$$$ of a cell. A cell is a peak iff its deficit is $$$\le 0$$$. How much can one operation reduce a deficit?
For $$$n,m \ge 2$$$, every operation reduces any deficit by at most $$$n+m-3$$$, and full-matrix operations achieve this bound for every cell at once. So the problem reduces to a $$$k$$$-th smallest value.
In one dimension a cell is a peak iff $$$2a_i \ge S$$$ (total sum). Only "full" operations and operations that skip one endpoint matter, and the two endpoint types are never both useful. The rest is a couple of linear inequalities solved in $$$O(1)$$$.
Let $$$R_x = \sum_j v_{x,j}$$$ and $$$C_y = \sum_i v_{i,y}$$$. The peak condition is equivalent to
If an operation covers $$$a$$$ cells of row $$$x$$$ and $$$b$$$ cells of column $$$y$$$, it changes the deficit by $$$-(a+b-3)$$$ when it covers $$$(x,y)$$$, and by $$$-(a+b)$$$ otherwise. For $$$n,m \ge 2$$$ this means the deficit is reduced by at most $$$n+m-3$$$ per operation: full coverage gives $$$a+b-3 \le n+m-3$$$, while an operation avoiding $$$(x,y)$$$ can cover cells of only one of the two lines, contributing at most $$$\max(n-1,m-1) \le n+m-3$$$.
Case $$$n,m \ge 2$$$. After $$$T$$$ operations, cell $$$(x,y)$$$ can be a peak only if $$$g_{x,y} \le T(n+m-3)$$$. Conversely, $$$T$$$ full-matrix operations make every cell with $$$\lceil g_{x,y}/(n+m-3)\rceil \le T$$$ a peak simultaneously. Hence the answer is the $$$k$$$-th smallest value of
Case $$$n=1$$$ or $$$m=1$$$. Rotate to a row of length $$$L=\max(n,m)$$$, sum $$$S$$$.
Peak condition: $$$a_i \ge S-a_i \iff h_i := S-2a_i \le 0$$$.
An operation on a segment of length $$$\ell$$$ subtracts 1 from each element inside.
If $$$i$$$ is inside: $$$h_i$$$ decreases by $$$\ell-2$$$
If $$$i$$$ is outside: $$$h_i$$$ decreases by $$$\ell$$$
Only three segment types are useful (others are dominated):
Full $$$[1,L]$$$: every $$$h_i$$$ reduced by $$$L-2$$$.
Skip‑first $$$[2,L]$$$: $$$h_1$$$ reduced by $$$L-1$$$, others by $$$L-3$$$.
Skip‑last $$$[1,L-1]$$$: $$$h_L$$$ reduced by $$$L-1$$$, others by $$$L-3$$$.
Only full operations: Same as the general formula with $$$n+m-3 = L-2$$$:
Answer = $$$k$$$-th smallest $$$\left\lceil \frac{S-2a_i}{L-2} \right\rceil$$$ (with $$$\max(0,\cdot)$$$). (This is exactly the xlim part in the code).
Full + one skip type, with an endpoint among the peaks: Assume the chosen endpoint is $$$p$$$ (either 1 or $$$L$$$), using $$$x$$$ full and $$$y$$$ skip‑$p$ operations ($$$T=x+y$$$). Take the other $$$k-1$$$ peaks as the cells with the largest $$$a_i$$$ (smallest $$$h_i$$$) among the remaining $$$L-1$$$ cells; let $$$v_k$$$ be the smallest of these. Reductions: - For $$$p$$$: $$$(L-2)x + (L-1)y = (L-2)T + y$$$ - For the other $$$k-1$$$ cells: $$$(L-2)x + (L-3)y = (L-2)T - y$$$
Requirements:
From the constraints:
(2) with $$$y=0$$$ gives $$$T \ge \lceil (S-2v_k)/(L-2) \rceil$$$
(1) with $$$y=T$$$ gives $$$T \ge \lceil (S-2a_p)/(L-1) \rceil$$$
Adding (1) and (2): $$$2(L-2)T \ge 2S-2a_p-2v_k \iff T \ge \lceil (S-a_p-v_k)/(L-2) \rceil$$$
Set
(If the first bound $$$\lceil (S-2v_k)/(L-2) \rceil$$$ were strictly larger, then $$$y=0$$$ is optimal and Strategy of only full operations already covers it.)
Now we must check whether there exists an integer $$$y$$$ satisfying the box constraints:
If this holds, $$$T=z$$$ is feasible and optimal for this endpoint; otherwise the endpoint strategy cannot beat the "only full operations" strategy.
The code’s solveL implements exactly this: it computes $$$z$$$, tests feasibility, and returns $$$z$$$ if valid or $$$\infty$$$ otherwise.
The final answer is $$$\min(\text{Strategy full},\; \text{solveL for left endpoint},\; \text{solveL for right endpoint})$$$.
Complexity: $$$O(nm)$$$ per test case.
import math
def ceil_div(a, b):
return (a + b - 1) // b
def solveL(v, v1, s, k):
n = len(v) + 1
if k == 1:
return max(0, ceil_div(s - 2 * v1, n - 1))
v.sort(reverse=True)
vk = v[k - 2]
z = max(ceil_div(s - v1 - vk, n - 2), ceil_div(s - 2 * v1, n - 1))
if min(z, (n - 2) * z - s + 2 * vk) >= max(0, s - (n - 2) * z - 2 * v1):
return z
return math.inf
T = int(input())
for _ in range(T):
n, m, k = map(int, input().split())
s = 0
u, rs, cs = [], [0] * n, [0] * m
v = []
for _ in range(n):
row = list(map(int, input().split()))
v.append(row)
s += sum(row)
rs[_] = sum(row)
for j in range(m):
cs[j] += row[j]
u.append(row[j])
if n + m <= 3:
u.sort()
if k == 1:
if n + m == 2 and u[0] < 0:
print(-1)
else:
print(0)
else:
print(abs(u[0] - u[1]))
continue
xlim = []
for i in range(n):
for j in range(m):
xlim.append(max(0, ceil_div(rs[i] + cs[j] - 3 * v[i][j], n + m - 3)))
xlim.sort()
ans = xlim[k - 1]
if m == 1 or n == 1:
ans = min(ans, solveL(u[:-1], u[-1], s, k))
ans = min(ans, solveL(u[1:], u[0], s, k))
print(ans)
A purchase is a transaction: spend an achievable amount $$$x$$$, gain rebate $$$r(x)$$$, net change $$$r(x)-x$$$. The achievable spends form a knapsack.
Below the smallest spend that yields a net increase, the balance only decreases; reachability is a DP on a DAG.
Above that threshold the balance can grow without bound, and every transaction changes it by a multiple of a single gcd. What determines whether $$$0$$$ is reachable?
If the smallest threshold does not exceed the cheapest product, every purchase is discounted and no positive balance can ever become $$$0$$$.
Let $$$V = \max(s, a_m)$$$ and compute the set $$$C$$$ of spend amounts achievable up to $$$V$$$ with an unbounded knapsack over the prices (a bitset, $$$O(V^2/64)$$$). The rebate for a spend $$$x$$$ is $$$r(x) = \max{b_j : a_j \le x}$$$, obtained by a prefix maximum.
For every achievable $$$x$$$:
- if $$$r(x) \lt x$$$, the net decrease is $$$d = x - r(x)$$$; keep $$$L[d] = \min{x}$$$ — the cheapest way to lose exactly $$$d$$$;
- if $$$r(x) \gt x$$$, the purchase increases the balance; let $$$\text{mnip}$$$ be the smallest such spend.
Below $$$\text{mnip}$$$. Every affordable transaction has $$$r(x) \le x$$$, so the balance only decreases. Define $$$f[0] = 1$$$ and
This is a DAG (all transitions go down); using the minimum spend for each decrease $$$d$$$ is optimal because a cheaper transaction is only more flexible. A shifted bitset computes all $$$f[i]$$$ in $$$O(V^2/64)$$$.
At or above $$$\text{mnip}$$$. A net-increasing purchase is affordable and can be repeated, so the balance can be made arbitrarily large. Every transaction changes the balance by a multiple of
so the residue of the balance modulo $$$g$$$ is invariant, and from a sufficiently large balance every value in the same residue class is reachable (Frobenius). Any path to $$$0$$$ must enter the decreasing region: for the last purchase, $$$b - x + r(x) = 0$$$ with $$$x \le b$$$ forces $$$r(x) = 0$$$ and $$$x = b \lt a_1$$$. Therefore a balance $$$i \ge \text{mnip}$$$ can reach $$$0$$$ iff $$$i \equiv 0 \pmod g$$$ and some positive balance below $$$\text{mnip}$$$ is reachable.
The second condition is automatic when $$$a_1 \gt c_{\min}$$$: the spend $$$c_{\min}$$$ (the cheapest product) has rebate $$$0$$$, so $$$f[c_{\min}] = 1$$$ and $$$c_{\min} \lt \text{mnip}$$$. Conversely, if $$$a_1 \le c_{\min}$$$, every purchase has $$$r(x) \ge b_1 \ge 1$$$, so a purchase of cost $$$x \le h$$$ leaves balance $$$h - x + r(x) \gt 0$$$ — no positive balance can ever become $$$0$$$.
Here $$$I$$$ and $$$D$$$ are the net increases/decreases found above, and the costs and $$$b_m$$$ stand in for the spends beyond $$$V$$$: for $$$x \ge a_m$$$ the net change is $$$x - b_m$$$, and since all achievable spends are multiples of $$$\gcd(c_1,\dots,c_n)$$$, the whole tail contributes exactly $$$\gcd(c_1,\dots,c_n, b_m)$$$.
Complexity: $$$O(V^2/64)$$$ time and $$$O(V)$$$ memory, with $$$V = \max(s, a_m) \le 125\,000$$$.
#include <bits/stdc++.h>
using namespace std;
const int maxV = 125000 + 5;
int Lgcd(const vector<int> &v) {
return accumulate(v.begin(), v.end(), 0, [](int a, int b) { return gcd(a, b); });
}
int main() {
int n, m, s;
scanf("%d %d %d", &n, &m, &s);
vector<int> c(n);
vector<pair<int, int>> ab(m);
for (auto &x : c)
scanf("%d", &x);
for (auto &[a, b] : ab)
scanf("%d %d", &a, &b);
ab.insert(ab.begin(), make_pair(0, 0));
m += 1;
bitset<maxV> p;
p.set(0);
for (int x : c)
p.set(x);
const int V = max(s, ab.back().first);
for (int i = 1; i <= V; ++i) {
if (p[i])
p |= (p << i);
}
vector<int> l(V + 1, s + 1);
l[0] = 0;
int mnip = s + 1;
vector<int> I, D;
for (int i = 1, abp = 0; i <= V; ++i) {
if (!p[i])
continue;
while (abp + 1 < m && ab[abp + 1].first <= i)
abp += 1;
auto [a, b] = ab[abp];
if (b <= i) {
l[i - b] = min(l[i - b], i);
D.push_back(i - b);
} else {
I.push_back(b - i);
mnip = min(mnip, i);
}
}
vector<pair<int, int>> lv;
for (int i = 1; i <= V; ++i) {
if (l[i] <= s)
lv.emplace_back(l[i], i);
}
const int ln = lv.size();
sort(lv.begin(), lv.end());
sort(c.begin(), c.end());
sort(I.begin(), I.end());
sort(D.begin(), D.end());
bitset<maxV> f, L;
f.set(0);
for (int i = 1, lp = 0; i < mnip; ++i) {
while (lp < ln && lv[lp].first <= i) {
L.set(maxV - lv[lp].second);
lp += 1;
}
f[i] = ((f & (L >> (maxV - i)))._Find_first() < V);
}
int Ig = Lgcd(I), Dg = Lgcd(D), cg = Lgcd(c);
int ugcd = gcd(gcd(Ig, Dg), gcd(cg, ab.back().second));
for (int i = 1; i < mnip; ++i)
puts(f[i] ? "YES" : "NO");
for (int i = mnip; i <= s; ++i)
puts((i % ugcd == 0 && ab[1].first > c[0]) ? "YES" : "NO");
return 0;
}
I promise I'll improve this soon. I know its unclear and skipped some steps for now.
Also check out:









Auto comment: topic has been updated by szdytom (previous revision, new revision, compare).
is it just me or B felt harder than C and D?
agreed
Not really for me, i actually struggled more with C because my dumb ahh couldnt realise it was just a dp for what felt like eternity. Also congrats on becoming specialist!
thanks!! :D
I think C and F are fraud problems,if you guess the conclusion and succeed,you will solve them immediately.
There is a whole lot of implementation and thinking through edge cases in F even if you were to "guess" the solution.
You're not the only one...
Oh this encourages me to try my first C problem on CF then 385216312 (Imagine a grinning emoji)
me too
Hell nah, B was like a 20 minute problem, but I got ja-baited by the test cases on C and thought it was greedy, and then you have to be not stubborn enough to switch the entire thought process to DP.
relatable
omg so relatable
yeah the tutorial soln is harder to realize, i did it like this
me too
Can anyone explain why taking the current maximum length is not optimal in C
1 2 3 1 4 2 3 4
if you choose "3" first, you can get 5^2 + 1^2 + 1^2 + 1^2 = 28.
But if you choose "1" and "4", you can get 4^2 + 4^2 = 32.
There could be 2 pairs with the same length that overlap eachother
For example : 5 4 3 3 4 6 5 2 2 1 1 6
You can see that both pair 5 and pair 6 have the same length which is 7, and you can only pick one pair only, because they overlap eachother , and in this case, picking pair 5 is better than picking pair 6, but you cannot determine which pair is better with greedy, therefore you have to use dp
your algorithm fail when the current maximum appear at least 2 times. Like this testcase: 5 1 2 2 3 1 4 5 3 4 5 At the first operation, you don't know which value you should choose (1 or 3)
D < C
It would be interesting to know how long it took the testers to solve problems C and D. Did they really solve D longer/worse than C?
its just dp it aint that hard
in my opinion C was the easiest problem, the easiest dp ever
I'm trying (and failing) greedy since yesterday.
How did you immediately understand it was DP along with the type of DP?
I also implemented the greedy idea and got WA t2, but after failing I thought about a counter example, I didn't find one, but I got the idea of what one would look like. If it's not greedy then you default to DP. Here's a counter example: https://codeforces.me/blog/entry/155640?#comment-1382284. For experienced coders, they pretty much didn't get fooled by the samples and went straight to the correct answer.
its pretty trivial, ill explain it to you.
Either, if the number you are handling/processing right now has already occured before that literally means you have the option to take it, but if you do take it you lose all of the numbers in between the pairs. So what matters? The thing that matters is the best value possible to get before the first occurence of that number, so either you dont take the pair and add 1 to it, or you take the pair and add the best value of the previous index where the first occurence happened.
With a simple example
0 1 2 3 4 5 6 7 (indexes)
1 2 3 1 4 2 3 4
here at position 6, either we can add 1 to it extending from position 5, or we can take the best one from index 1 right before the first occurence of "3" in the array, and the maximum value at that index will be the best value at that index. Note, either you can take a pair or you cant, but if you do you lose everything in between the pairs. So, We basically have 2 options every time, but instead of a n^2 solution iterating through all possible 2 options we can maintain a dp to store the best maximum value at each position i so that we can use it later. That was my observation.
i hope that helps :D
Hey can anyone help me out why a greedy strategy does not really work for problem C. Here's my submission: https://codeforces.me/contest/2248/submission/385189701
Never mind, I have understood it I believe
szdytom I have a counter example of problem B where editorial solution fails --
Edit- solution is correct, I gave testcase in wrong format
test case should be
and this test passed.
yes thanks
[Deleted]
:sob:
For D's bonus question,
We can store an array $$$a$$$ of length where $$$a_i=1$$$ if $$$s_i=t_i$$$ else $$$a_i=0$$$
for a subarray to be good, the number of positions containing equal characters should be greater than or equal to the number of positions containing different character
in other words, for a subarray to be good, the corresponding subarray in $$$a$$$ should have $$$1$$$ as it's mode
we can use prefix sum to count the number of subarrays that satisfy the condition $$$2*(a_l+a_{l+1}+...+a_r) \ge r-l+1$$$
This can be done in O(n^2). Is there a better aproach than this???
I may be wrong but isn't your solution failing on this?
i forgot that $$$s_i=0;t_i=1$$$, $$$s_j=1;t_j=0$$$ are both possible :(
I overcomplicated D by doing binary search: 385178994
Suppose the whole array a and b are not the same mode (if they are the same then it is always good by selecting the whole array). I binary searched to find if the minimum number of elements I can delete so that both arrays have the same mode (if anyone is interested I can explain further in detail)
My contest discussion stream here for ABCDE
Problem C has a tag "greedy", could anyone explain greedy approach or drop the code in a comment
link C is insanely similar to this problem. I somehow solved that problem just a few hours before the contest. What a coincidence
$$$D$$$ really should have been the harder version (Bonus Problem ) . It's far easier for a $$$Div-2$$$ $$$D$$$
The contest was kinda weird
Hard B, Easy D, dp C (compared to usual div2 B/D)
Managed to get E tho
Hi guys, I'm getting WA on test 2 with this submission on problem B:
385171329
I believe it is logically equivalent to the editorial.
My checks are:
The last condition is just the editorial's b[i] < a[n — m + i] written in reverse order.
I've compared the logic several times, and I can't see the difference between my implementation and the editorial. If anyone can point out the mistake or provide a counterexample, I'd really appreciate it.
I think you may print "NO" more than once per test case in some cases
Thanks! That was exactly the problem. I spent too much time looking for a logical mistake, I completely overlooked it. Thank you for spotting it!
Yes I think the problem is that you forgot to return from function in n < 2 * m check.
Thanks for checking! The issue wasnt the logic at all, it printed "NO" more than once for a case because I didnt return it, just like you said. I appreciate the help!
Can someone explain their intuition for solving $$$E$$$? It's such a bizarre (but interesting!) question, but even more bizarre that so many people solved it in the contest.
I completely agree. Besides the intuition, I'd also love to know if there are any classic problems with a similar idea. It feels like this problem is based on a well-known technique that I've somehow missed.
maybe it's only because that there are so many cheaters(:
I made a comment below which may help. I didn't add a solution but if people want to see it I can.
2248E - Excuse for Breaks
Let's use the first test case as a running example:
n = 6, m = 4, d = 3p = {2, 3, 4, 5}r = {5, 9, 1, 3}1. Cyclic representation
It is useful to imagine both
pandrextended infinitely, cyclically:p = {2, 3, 4, 5, 8, 9, 10, 11, ...}r = {5, 9, 1, 3, 5, 9, 1, 3, ...}Let
psrdenote the prefix sums ofr:psr = {5, 14, 15, 18, ...}2. Form of
f(I(a))For any arbitrary length
a,f(I(a))has the formpsr[m] * x + psr[y]where
x >= 01 <= y < mand
x, yare integers.3. How does
adiffer fromI(a)?If
I(a)looks like111111111111111...then
ahas the form[111...111][000...000][111...111][000...000]...In other words, some all-
1segments ofI(a)are replaced by segments of the form[000...000][111...111]4. Consider one such replacement
Suppose we replace
where
xandyare the corresponding segment lengths.5. Replacement profit
Placing a
0resets the countercto0. Hence, the following block of1s starts accumulating rewards from the beginning ofr, giving a prefix ofr. Without the reset,I(a)continues from its current position in the cycle, giving a segment ofr. The termx * dis the cost of replacingxones with zeros.Define the profit of this replacement as
rp = cost(a[j...k]) - cost(I(a)[i...k]) - x * dWe want to maximize
rp. Here,cost(a[j...k])is the sum of some prefix of the cyclic array
r, whilecost(I(a)[i...k])is the sum of some segment of the cyclic array
r. Therefore,rp = prefix_sum(r) - segment_sum(r) - x * d6. What should
xbe?Decreasing
xincreases-x*d, and therefore increasesrp. Hence we should minimizex. Sincex = 0means that no replacement actually happens, the minimum relevant value isx = 1Thus,
rp = prefix_sum(r) - d - segment_sum(r)So the problem reduces to comparing a prefix sum of
rwith a segment sum ofr.7. How many prefixes/segments need to be considered?
Because
ris cyclic, we do not need to consider prefixes of length>= m. If a prefix contains at least one complete cycle, its corresponding segment also contains an overlapping complete/suffix part that can be removed from both sides without changing the relevant comparison. Therefore, it is sufficient to consider prefix lengths1, 2, ..., m - 1Similarly, because of cyclicity, there are only
mdistinct starting positions for the segment ofr. So we have:prefixes: O(m)segments: O(m)8. What type of relation do we need to consider?
For one replacement, let
rp = x - ywhere
x = prefix_sum(r) - dy = segment_sum(r)We are interested in whether the total replacement profit can be positive.
- One-to-one
One prefix replaces one segment:
rp = x - yFor
rp > 0, we needx > y- One-to-many
Suppose one prefix corresponds to
zsegments:rp_total= rp1 + rp2 + ... + rpz= (x - y1) + (x - y2) + ... + (x - yz)= z*x - (y1 + y2 + ... + yz)If
rp_total > 0, then necessarilyx > min(y1, y2, ..., yz)Therefore, at least one individual
rpi > 0. Hence a profitable one-to-many replacement implies the existence of a profitable one-to-one replacement, so it is sufficient to consider the latter.- Many-to-one
This is not possible: a single segment cannot be replaced by multiple prefixes.
- Many-to-many
This can be decomposed into a combination of one-to-one and one-to-many relations. Since any profitable one-to-many relation can further be reduced to a profitable one-to-one relation, it is again sufficient to consider only one-to-one replacements. Therefore, we only need to consider a one-to-one relation between:
one prefix of r, of length 1 ... m-1and
one cyclic segment of r, with at most m distinct possibilities.9. Complexity
This suggests an O(m^2) approach possibility.
$$$O(m^2)$$$ (two pointers): 385222304
$$$O(m^2 \log m)$$$ (binary search): 385196979
1000 contest rating first.And l solved AB uncommonly.For B,l think that we can find two numbers named n1 and n2(n1 >= bi,n2 <= bi)(0 <= i <= m-1) and delete both of them.If we can't find numbers from a to match all numbers from b, print "NO" or "YES".385158820
I did the same! Turns out that the other way was actually more trivial and easier. But as long as it is accepted, I won't complain at all, lol
It's my first time to enter contest....and I didn't even solve B....I feel even doubt myself....Is anyone feel the same with me
Here is a (hopefully more intuitive) reformulation of E:
You and your friend go rock climbing. The rock wall (with height $$$n$$$) is very slippery, so if you ever take a break you will fall back down to the bottom. You will compete to see who can get the highest score.
Scoring works as follows:
Your friend is very hyper, and he will climb up to the top repeatedly (returning to the ground each time he reaches the top).
Determine if there exists a strategy so you have more points than your friend at ANY point in time.
The reformulation is very close to how the problem was initially proposed! And that's why it's called "excuse for breaks". However we finally decided to rewrite the statement in pseudo code for clarity.
The proofs of A and B are amazing.
Problem E has a tag binary_search, but the solution doesn't use it.
Most people uses binary search actually. The tag is meant to cover all solutions.
Great round! Problem G was definitely the highlight for me. The idea of splitting the state space and conquering the problem in two parts (DP + GCD) is extremely neat. Really enjoyed the problem design!
Problem B can be solved by normal simulation and i think its much easier to realize than the mathematical proof in tutorial.
I stored both
aandbelements in one array sayc(with their type, 1 means from arrayaand 0 means from arrayb)sort array
cso by problem statement we simply understand that for each element
bthere has to be atleast 1 element ofaless thanb(to its left inc) and atleast 1 element ofagreater thanb(to its right inc)This can be checked with two simple iteration
Forward: keep a dynamic counter for
aelements, when i encounter abelement, i decrement the counter (this means i immediately resolve with an availableawhich is less thanbi) if the counter is 0 and we encounterbelement means there is no elementa<bihence instantNOBackward: exact same counter logic backwards for an available
a>bicode: 385141172
TC: O((n+m)log(n+m)).
szdytom was there any reason in problem B that the elements are supposed to be distinct ?
The solution does not really change right if there are multiple occurrence of n , in A and B . Its always optimal to ignore these in pairs, and just use the remaining in either A or B for the greedy approach .
Was this done for easier implementation or am i mistaken here ?
You are right, just for easier implementation since it's already a bit hard for B in my opinion.
Here is a (almost definitely) wrong solution to E that get's AC. Feel free to hack my solution.
I look for a solution of the form
I(x)[0]I(y), wherex == p[i]for somei. I simulate the nextntime periods for bothI(x+y+1)andI(x)[0]I(y), but only look at times where one of them has a payday (get's ther[i]points).I handle the logic for checking if I've simulated at least
ntime periods incorrectly. Originally I was going to stop if the first pointer hits index0for the second time. But the way I have implemented it, I may increasep1vis0countmore times then I should. Setting the cap for the while loop at4get's AC, but I think this is definitely hackable.Hi great Editorial
Problem F editorial: 1) It seems there is a typo:
Should be not L-1, but L-2.
2) How do you come from (L−2)T−y≥c1 to T = max(..., ⌈c1L−2⌉), why "y" has just disappeared?
I solved F by ternary search on 2 intervals. Can't realize the straight formula solution from editorial...
You are right. I'm too sleepy yesterday and parts of the original reasoning is just pure bullshit. I've rewrote that part now, hopefully it is now understandable.
Thank you for update and for good problemset.
In problem D: u0+x0≥⌈k/2⌉ and u0+y0≥⌈k/2⌉, which imply |x0−y0|≤u0+v0
How does that imply?
I skipped some steps. I've expanded it to a very detailed reasoning (with the help of LLM) including the answer to your question. Hopefully the can help :)
Yeah, thanks, it helped. I wonder if someone bothered to prove necessity during contest. I personally only did sufficiency and hoped it would work
A very simple way to solve B:
Since all the n+m numbers are distinct. We must have n — m > m or n > 2m.
For each number in B to get generated from two numbers in A, we must have one smaller as well as larger element present in A.
Thus, sort A and B.
Check A[i] < B[i] for all i. --> One smaller present which will not be exhausted from previous element.
Check A[i-th from last] > B[i-th from last] --> One larger present which will not be exhausted from next element.
Code: https://codeforces.me/contest/2248/submission/385352600
same solution as me, same solution as editorial
How to do the bonus problem D better than O(n^2)?
For D's bonus question,
We can solve this problem efficiently in the online mode using two Segment Trees.
Let's define the prefix counts of specific 2-character patterns as follows:
C0011 = count(00) + count(11)C0110 = count(01) − count(10)We want to satisfy the absolute difference condition:
abs∣C0110[r]—C0110[l]∣ ≤C0011[r]−C0011[l]Removing the absolute value splits our condition into two cases depending on the relative values of
C0110[r]andC0110[l]:Case 1:
C0110[r]≥C0110[l]The inequality simplifies to:
C0011[r] − C0110[r]≥C0011[l] − C0110[l]We need to count the number of valid left endpoints
l ≤ rthat satisfy this inequality.Case 2:
C0110[r]<C0110[l]The inequality opens with the opposite sign,:
C0011[r] + C0110[r]≥C0011[l] + C0110[l]Similarly, we count the number of valid
l ≤ rsatisfying this condition.To handle these two conditions dynamically for online queries, we can maintain two separate
Segment Trees:For each query up to index
r, we query the respective segment tree based on whetherC0110[r]is greater than or less thanC0110[l], allowing us to efficiently count the valid ranges inO(logn)time per query.TC :
O(nlogn)In F as per editorial, we fixed z and we are trying to get a possible interval for y, if its not possible for the z we choosed, why can't we try for z+1 ? Please let me know if I'm missing something
Upd: Understood, after checking the case where y might not get an interval, I can observe that our intuition of z >= (s-2*vk)/(L-2) is not possible. So if y does not get an interval then we go for full.
I was able to figure out D easily but couldn't even begin B & C. Really need to work on my DP
I think a part of the presented solution to E is incorrect. In particular, the part after "Induct on the number of runs". How does $$$S_x+S_{|t|}+\max(M,0) \leq S_{|s|} + \max(M, 0)$$$ follow from $$$S_x+S_{|t|}−S_{x+|t|+1} \leq M$$$? It only follows if $$$M \leq 0$$$.
The conclusion, and of course, the solution is correct. But induction only works if $$$M \leq 0$$$. I think the author wanted to prove that $$$F_{|s|} \leq S_{|s|}$$$ when $$$M \leq 0$$$. In that case, a modified (and simplified) induction proof works. Otherwise if $$$M \gt 0$$$, we don't need to prove anything because we already have a working solution.
My reasoning is that in our strategy, we should reset (do a 0 and go back to the bottom) exactly once.
Proof: let's say we reset at point A and point B. If resetting at point A doesn't immediately win the game already, then at point B, our value will be <= the opponent's value (or else we have already won). So if we just don't reset at A, then we will be at our opponent's value at point B, and thus resetting at only point B gets us the same or better result.
Then for implementation basically we brute force on our second half (after resetting): take 1, 1/2, 1/2/3, 1/2/3/.../m, and use two pointers to look for any section where we can beat them. I chose to say that taking each index actually gives 0 and resetting subtracts d. So then I just have to find a window in the original array where the sum of
r[i]is less than the sum of our second half.C is beautiful nice contest
Bonus questions for d can be solved via sliding window , right?