Thank you for participating !
Special Thanks to hxu10 for giving me the chance to write the editorial and for maomao90 for enhancing the editorial !.
Editorial of Problems E and F are written by hxu10, and the rest are written by me. I hope they're insightful and concise, please let me hear your opinion about it or any feedback in general 💙.
2156A - Pizza Time
Since $$$m_1 \le m_2$$$, the total number of slices Alice ate is always at least as much as the total number of slices Bob ate. What's optimal construction ?
We want to try to minimize the difference between the total number of slices Alice ate and the total number of slices Bob ate.
The optimal construction is to let both $$$m_1$$$ and $$$m_2$$$ to be equals to one. The sequence of operations, denoted by $$$(m_1, m_2, m_3)$$$, is as follows:
The general form of the sequence
Note that we're considering the operations when $$$m_1 \le m_2 \le m_3$$$.
Consider the case where $$$n$$$ is even:
The number of operations is the length of the sequence $$${2,4,6,\ldots, 2(\frac{n}{2}-1)}$$$ which is $$$\frac{n}{2}-1$$$.
Consider the case where $$$n$$$ is odd:
The number of operations is the length of the sequence $$${1,3,5,7,\ldots, 2(\lfloor \frac{n}{2} \rfloor-1)+1}$$$
By the representation of odd numbers we've $$${2(0)+1,2(1)1+,\ldots, 2(\lfloor \frac{n}{2} \rfloor-1)+1}$$$ , which is equivalent to the length of $$${0,1,2,\ldots, \frac{n-1}{2}-1}$$$ which gives the length of $$$\frac{n-1}{2}$$$.
Both cases are equivalent to the close form
Complexity $$$\mathcal{O}(1)$$$.
from math import *
def solve():
n=int(input())
print((n-1)//2)
for _ in range(int(input())):
solve()
It's possible to use fair split that's we use $$$\lfloor \frac{n}{3} \rfloor , \lfloor \frac{n}{3} \rfloor , \lfloor \frac{n}{3} \rfloor + n \bmod 3$$$ and keep simulating with $$$n=m_3$$$ on steps except the first step until you reach $$$m_2 \le 2$$$.
Complexity $$$\mathcal{O}(\log_3(n))$$$
from math import *
def solve():
n=int(input())
a,b,c=n//3,n//3,n//3+(n%3)
ans=0
while(n>2):
ans+=n//3
n=n//3+(n%3)
print(ans)
for _ in range(int(input())):
solve()
2156B - Strange Machine
What's the consuming part of processing the string of operations $$$s$$$ ?
If the string $$$s$$$ contained at least one $$$\mathtt{B}$$$ operation , What's the maximum count of iterations we're going to run so that $$$a=0$$$ ?
If the string $$$s$$$ contains $$$x$$$ copies of $$$\mathtt{B}$$$ then $$$a$$$ is guaranteed to be $$$a=0$$$ in at most $$$\mathcal{O}(\log_{2x} A)$$$ where $$$A=\max(a_1,a_2,\ldots ,a_n)$$$ , that's at most $$$\mathcal{O}(n \log_2 A) \sim \mathcal{O}(30n)$$$ operations are required .
How to manage too many appearances of $$$\mathtt{A}$$$ for efficiency ?
It's enough to handle the case where $$$\underbrace{\color{red}{\mathtt{AAAAA\ldots AAA}}}_{}$$$ that's the answer for query $$$a$$$ is $$$a$$$ because we're incrementing by 1 at each iteration ; otherwise the complexity becomes $$$\mathcal{O}(10^9q)$$$ for such cases which is slow. and the rest can be done in $$$\mathcal{O}(nq \log_2(10^9))$$$ which is safe according to the constraints.
If you've one $$$\color{blue}{\mathtt{B}}$$$ in string $$$s$$$ , then you'll have to do operations in $$$\mathcal{O}(n\log_2(A))$$$ which is $$$\sim \mathcal{O}(20 \cdot 30)$$$ which is fine for $$$n \le 20$$$ and $$$\sum q \le 10^4$$$ , at worst case this is roughly $$$\mathcal{O}(6 \cdot 10^5)$$$ which is safe.
If we've a string $$$s$$$ that's all $$$\color{red}{\mathtt{A}}$$$ i.e. :
then answer is simply for each $$$a_i$$$ is $$$a_i$$$ itself because we cannot do anything except just subtracting by $$$1$$$ many times ; otherwise the complexity becomes $$$\mathcal{O}(10^9q)$$$ for such cases which is slow.
Complexity $$$\mathcal{O}(nq \log_2(10^9))$$$.
def solve():
n,q=map(int,input().split())
s=input().strip()
a=list(map(int,input().split()))
A,B=s.count('A'),s.count('B')
for i in range(q):
if(B==0):
print(a[i])
else:
ans=0
while(a[i]):
for j in s:
if(a[i]==0):break
ans+=1
if(j=='A'):a[i]-=1
else: a[i]//=2
print(ans)
for _ in range(int(input())):
solve()
Compress the string $$$s$$$ into sequence of "Move Blocks" that's for $$$s=\mathtt{AABBBABAAA}$$$ the sequence of moves will be
Be careful in simulation
Observation : The consuming part of processing the operations where a segment of $$$\underbrace{\color{red}{\mathtt{AAAAA\ldots AAA}}}_{}$$$ because we're processing one by one which is inefficient and answering query will take $$$\mathcal{O}(nq \log_2(10^9))$$$ , why ? , because processing $$$\underbrace{\color{red}{\mathtt{AAAAA\ldots AAA}}}_{}$$$ operation-by-operation is slow , for example consider the sequence $$$\underbrace{\color{red}{\mathtt{AAAAA\ldots AAA}} \color{blue}{\mathtt{B}}}_{}$$$
This case will take $$$\mathcal{O}(nq \log_2(10^9))$$$ at worst case , which is inefficient.
A good way to optimize is by compress the blocks of same type of operations as $$$(\mathrm{type},\mathrm{count})$$$ that way all long blocks of $$$\color{red}{\mathtt{A}}$$$ will be performed much faster , For blocks of $$$\color{blue}{\mathtt{B}}$$$ it's already fast to process them in order because of $$$\mathcal{O}(\log_2(a))$$$ and it reduces $$$a$$$ to $$$0$$$ in $$$\mathcal{O}(\log_2(10^9)) \sim 30$$$ at most , However compressing the operations is still better to compose the operations.
That's we're going to process at most $$$\sim 60$$$ blocks , because if we started with $$$\color{red}{\mathtt{A}}\color{blue}{\mathtt{B}}\color{red}{\mathtt{A}}\color{blue}{\mathtt{B}}\color{red}{\mathtt{A}}\color{blue}{\mathtt{B}}\ldots $$$ assuming $$$a=10^9$$$ , which is the worst case of the algorithm.
Now after composing the blocks as $$$(\mathrm{type},\mathrm{count})$$$ , you should iterate through them :
- If $$$s_i=\color{red}{\mathtt{A}}$$$ then we perform $$$a_i=a_i-\min(\mathrm{count},a_i)$$$
- If $$$s_i=\color{blue}{\mathtt{B}}$$$ then we perform $$$\displaystyle a_i=\left \lfloor \frac{a_i}{\displaystyle 2^{\min(\text{count},\lceil \log_2(n) \rceil)}} \right \rfloor$$$
make sure to update number of operations accordingly.
Complexity $$$\sim \mathcal{O}(n+q \log^2(10^9))$$$.
def solve():
n,q=map(int,input().split())
s=input()
a=list(map(int,input().split()))
A=s.count('A')
B=s.count('B')
last=s[0]
seq=[]
cur=1
for i in range(1,n):
if(s[i]==last): cur+=1
else:
seq.append([last,cur])
cur=1
last=s[i]
if(cur!=0): seq.append([last,cur])
if(B==0):
for i in a: print(i)
else:
for i in range(q):
ans=0
while(a[i]>0):
for j in seq:
if(a[i]==0): break
if(j[0]=='A'):
mn=min(j[1],a[i])
ans+=mn
a[i]-=mn
else:
if a[i]==0: break
x=a[i]
p=0
while(x):
x//=2
p+=1
mn=min(p,j[1])
ans+=mn
a[i]//=(2**mn)
print(ans)
for _ in range(int(input())):
solve()
2156C - Maximum GCD on Whiteboard
You can do all the Erase operations before the Split operations.
Suppose there exists an optimal solution where you do an Erase operation on an element that was produced from a Split operation. You can instead do an Erase operation on the original element that it was being Split from, which will result in the whiteboard containing a subset of the elements in the optimal solution. Hence, it will have a beauty of at least as much as the optimal solution.
Fix a target gcd $$$g$$$. Which numbers can be made divisible by $$$g$$$ using the Split operation?
If $$$x$$$ is a multiple of $$$g$$$, we do not need any Split operation. If $$$x\ge 4g$$$, one split can result in two multiples of $$$g$$$ (discard the middle).
Split $$$x$$$ into $$$(g, g + x\bmod g, x - 2g - x\bmod g)$$$. Both $$$g$$$ and $$$x - 2g - x\bmod g$$$ are divisible by $$$g$$$.
- If $$$x \lt 5g$$$, $$$x - 2g - x\bmod g = 2g$$$. $$$g + x\bmod g \le 2g = x - 2g - x\bmod g$$$, hence, $$$x_1 \le x_2 \le x_3$$$ is satisfied.
- Otherwise, $$$x \ge 5g$$$. $$$x - 2g - x\bmod g \ge 5g - 2g - g = 2g \ge g + x\bmod g$$$, hence, $$$x_1 \le x_2 \le x_3$$$ is satisfied.
Conversely, if $$$x\lt 4g$$$ and $$$x$$$ is not divisible by $$$g$$$, you can’t make it good by splits → it must be erased.
We will prove this by strong induction.
Let $$$P_i$$$ be the statement: $$$i$$$ cannot be made divisible by $$$g$$$ using any number of splits if $$$i \lt 4g$$$ and $$$i$$$ is not divisible by $$$g$$$.
Base case: $$$P_1$$$ is true as $$$1$$$ cannot be split.
Suppose $$$P_i$$$ is true for all $$$i \lt K$$$ for some $$$K \ge 2$$$. We will prove that $$$P_K$$$ is also true.
If $$$K \ge 4g$$$ or $$$K$$$ is divisible by $$$g$$$, $$$P_K$$$ is vacuously true. From here on, we will assume that $$$K \lt 4g$$$ and $$$K$$$ is not divisible by $$$g$$$.
Suppose we split $$$K$$$ into $$$x_1\le x_2\le x_3 \lt K$$$. If either $$$x_1$$$ or $$$x_3$$$ is not divisible by $$$g$$$, $$$P_{x_1}$$$ and $$$P_{x_3}$$$ implies that they can never be made divisible by $$$g$$$ using any number of splits. Hence, if we want to make $$$K$$$ divisible by $$$g$$$, $$$x_1$$$ and $$$x_3$$$ have to both be divisible by $$$g$$$.
If $$$x_1 \ge 2g$$$, $$$x_3 \ge x_2 \ge x_1 \ge 2g$$$, which means that $$$K = x_1 + x_2 + x_3 \ge 2g + 2g + 2g = 6g$$$, which contradicts $$$K \lt 4g$$$. Hence, $$$x_1 = g$$$ is the only possibility.
- If $$$x_3 = g$$$, $$$x_1 \le x_2 \le x_3 \rightarrow g \le x_2 \le g$$$. Hence, $$$x_2 = g$$$ as well, and $$$K = x_1 + x_2 + x_3 = g + g + g = 3g$$$, contradicting that $$$K$$$ is not divisible by $$$g$$$.
- If $$$x_3 \ge 2g$$$, $$$K = x_1 + x_2 + x_3 \le g + g + 2g = 4g$$$, contradicting $$$K \lt 4g$$$.
Hence, it is not posible to make $$$K$$$ divisible by $$$g$$$ using any number of splits.
So $$$g$$$ is good if
Count with a frequency array / map and a prefix sum for $$$g=1,2,\ldots ,n$$$
We want the maximum gcd $$$g$$$ achievable after $$$\le k$$$ erases and any splits.
For a fixed $$$g$$$, the elements that won’t consume an erase are:
- all multiples of $$$g$$$ (already good), and
- any $$$x\ge 4g$$$ (can be made good via one split using the construction in hint 3).
Thus, the only "bad" numbers (that would have to be erased) are those with $$$x\lt 4g$$$ that are not multiples of $$$g$$$. Therefore $$$g$$$ is good if
Since $$$1\le a_i\le n$$$, precompute a frequency array and prefix sums $$$p[v]=\sum_{u\le v}f[u]$$$. Then
Iterate through $$$g=1,2,3,\ldots ,n$$$ and keep the largest good $$$g$$$.
Complexity : $$$\mathcal{O}(n)$$$.
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
int n,k;cin>>n>>k;
vector<int>a(n),mp(n+1),p(n+1);
for(auto &i:a){
cin>>i;
mp[i]++;
}
for(int i=1;i<=n;i++){
p[i]=p[i-1]+mp[i];
}
int ans=1;
for(int g=1;g<=n;g++){
int t=min(n,4*g-1);
int good=n-p[t];
if(g<=n)good+=mp[g];
if(2*g<=n)good+=mp[2*g];
if(3*g<=n)good+=mp[3*g];
if(good>=n-k)ans=g;
}
cout<<ans<<"\n";
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t;cin>>t;
while(t--)solve();
}
2156D - Find the Last Number
We determine the $$$k$$$-th bit of $$$p_n$$$ for $$$k=0,1,\ldots,\lfloor\log_2 n\rfloor$$$.
Let $$$\text{bit}_k(i)$$$ denote the whether the $$$k$$$-th bit of $$$i$$$ is zero or one. How can we determine the $$$k$$$-th bit of $$$p_n$$$, i.e. $$$\text{bit}_k(p_n)$$$, from $$$\text{bit}_k(p_1) + \text{bit}_k(p_2) + \ldots + \text{bit}_k(p_{n - 1})$$$?
How can we achieve this halving?
Recall from Hint 2 that $$$\text{bit}_k(i)$$$ is defined as $$$k$$$-th bit of the integer $$$i$$$. A naive solution using $$$n\log_2 n$$$ queries is as follows:
Compute $$$\text{bit}_k(p_1) + \text{bit}_k(p_2) + \ldots + \text{bit}_k(p_{n - 1})$$$ for all $$$k=0,1,\ldots,\lfloor\log_2 n\rfloor$$$.
- $$$\text{bit}_k(p_i)$$$ can be computed with a single query $$$p_i \ \mathtt{AND} \ 2^k$$$ ($$$1\le i\le n - 1$$$).
If $$$\text{bit}_k(1) + \text{bit}_k(2) + \ldots + \text{bit}_k(n) = \text{bit}_k(p_1) + \text{bit}_k(p_2) + \ldots + \text{bit}_k(p_{n - 1})$$$, it means that the $$$k$$$-th bit of $$$p_n$$$ is zero. Otherwise, it is one.
- This works due to the fact that $$$\text{bit}_k(p_1) + \text{bit}_k(p_2) + \ldots + \text{bit}_k(p_{n - 1}) = \text{bit}_k(1) + \text{bit}_k(2) + \ldots + \text{bit}_k(n) - \text{bit}_k(p_n)$$$.
To optimise this, we will half the search space after each step. Starting from $$$k = 0$$$, we still use $$$n - 1$$$ queries to calculate $$$\text{bit}_k(p_1) + \text{bit}_k(p_2) + \ldots + \text{bit}_k(p_{n - 1})$$$. After using this to determine the value of the $$$0$$$-th bit of $$$p_n$$$, we can discard all $$$p_i$$$ that has a different $$$0$$$-th bit from $$$p_n$$$.
More formally, let $$$S_0$$$ denote the set of elements $$$i$$$ such that $$$i$$$ has the same $$$0$$$-th bit as $$$p_n$$$, and $$$P_0$$$ denote the set of elements $$$i$$$ ($$$1\le i\le n - 1$$$) such that $$$p_i$$$ has the same $$$0$$$-th bit as $$$p_n$$$. $$$\sum_{i\in P_0} \text{bit}_1(p_i) = \left(\sum_{i\in S_0} \text{bit}_1(i)\right) - \text{bit}_1(p_n)$$$, so the $$$1$$$-st bit of $$$p_n$$$ is zero if $$$\sum_{i\in P_0} \text{bit}_1(p_i) = \sum_{i\in S_0} \text{bit}_1(i)$$$.
In general, we can let $$$S_k$$$ denote the set of elements $$$i$$$ such that $$$i$$$ has the same $$$0$$$-th, $$$1$$$-st, $$$\ldots$$$ , $$$k$$$-th bit as $$$p_n$$$, and $$$P_k$$$ denote the set of elements $$$i$$$ ($$$1\le i\le n - 1$$$) such that $$$p_i$$$ has the same $$$0$$$-th, $$$1$$$-st, $$$\ldots$$$ , $$$k$$$-th bit as $$$p_n$$$. Then, the $$$k$$$-th bit of $$$p_n$$$ is zero if $$$\sum_{i\in P_{k-1}} \text{bit}_k(p_i) = \sum_{i\in S_{k-1}} \text{bit}_k(i)$$$.
Observe that $$$|P_k| \le \left\lceil \frac{|P_{k - 1}|}{2} \right\rceil$$$ for all $$$k\ge 1$$$. Hence, the total number of queries used is
def query(index,num):
print("?",index,num)
return int(input())
def main():
n = int(input())
rest = set()
likely = set()
for i in range(1,n):
rest.add(i)
for i in range(1,n+1):
likely.add(i)
D = len(bin(n)[2:])
ans = 0
for d in range(D):
index_0 = set()
index_1 = set()
likely_0 = set()
likely_1 = set()
for index in rest:
res = query(index, 1<<d)
if res == 0:
index_0.add(index)
else:
index_1.add(index)
zeros = 0
ones = 0
for num in likely:
if num & (1<<d):
ones += 1
likely_1.add(num)
else:
zeros += 1
likely_0.add(num)
if zeros == len(index_0):
ans += 1 << d
rest = index_1
likely = likely_1
elif ones == len(index_1):
rest = index_0
likely = likely_0
else:
print("Error")
return
print("!",ans)
T = int(input())
t = 1
while t <= T:
main()
t += 1
2156E - Best Time to Buy and Sell Stock
Consider the simplified version of the game where Alex moves first.
Suppose Alex wants to ensure a beauty of at least $$$g$$$ (the goal), while Hao tries to keep it below $$$g$$$. Which indices should Alex lock to achieve this goal?
We can binary search on the goal $$$g$$$.
For a given $$$g$$$ and an index $$$i$$$, we define $$$f_g(a, i)$$$ as the number of indices $$$j\neq i$$$ satisfying $$$a_{\max(i, j)} - a_{\min(i, j)} \ge g$$$.
If there exists an index $$$i$$$ such that $$$f_g(a, i) \ge 2$$$, then Alex can lock index $$$i$$$ on the first move. No matter which index Hao removes next, there will still exist at least one $$$j$$$ such that $$$|a_i - a_j| \ge g$$$. Thus, Alex can secure that pair and guarantee a beauty of at least $$$g$$$.
If $$$f_g(a, i) \le 1$$$ for all indices $$$i$$$, Alex cannot achieve his goal. Whichever index $$$i$$$ Alex locks first, Hao can remove the single $$$j$$$ such that $$$|a_i - a_j| \ge g$$$. Hence, Alex will never be able to lock two indices with a difference $$$\ge g$$$, and the resulting beauty will be strictly less than $$$g$$$.
Now return to the original problem, where Hao moves first.
To keep the final beauty below $$$g$$$, Hao must remove an index such that after the removal, $$$f_g(a, i) \lt 2$$$ for all $$$i$$$. Otherwise, Alex will have a winning move as shown in Hint 1.3.
For each $$$i$$$, we only need to track whether $$$f_g(a, i)$$$ is $$$0$$$, $$$1$$$, $$$2$$$, or greater than $$$2$$$. This is because if there are any index $$$i$$$ with $$$f_g(a, i) \gt 2$$$, Hao has to remove index $$$i$$$ on his first move. Otherwise, we will have $$$f_g(a, i) \ge 2$$$ after Hao's first move, allowing Alex to have a beauty of at least $$$g$$$ as mentioned in Hint 2.
This observation allows us to compute $$$f_g(a, i)$$$ efficiently.
Read the above hints before continuing.
As noted in Hint 1.2, we can binary search on the target beauty $$$g$$$.
For each index $$$1 \le i \le n$$$, recall that $$$f_g(a, i)$$$ is the number of indices $$$j\neq i$$$ satisfying $$$a_{\max(i, j)} - a_{\min(i, j)} \ge g$$$.
As mentioned in Hint 3, we only care whether $$$f_g(a, i)$$$ is $$$0$$$, $$$1$$$, $$$2$$$, or greater than $$$2$$$. We iterate through $$$i = 1, \ldots, n$$$, and maintain the three smallest previous values $$$a_j$$$ (for $$$j \lt i$$$). For each of these, we check whether the condition holds and increment both $$$f_g(a, i)$$$ and $$$f_g(a, j)$$$ if it does. This leads to an $$$\mathcal{O}(3n) = \mathcal{O}(n)$$$ computation per $$$g$$$.
We simulate each possible first move $$$p$$$ by Hao. Let array $$$b$$$ be array $$$a$$$ after removing index $$$p$$$. When Hao removes index $$$p$$$, only the $$$f_g(a, p)$$$ indices $$$q$$$ satisfying $$$|a_p - a_q| \ge g$$$ will have their $$$f_g(b, q) = f_g(a, q) - 1$$$, while all others remain unchanged.
Hao succeeds in keeping the beauty below $$$g$$$ if and only if removing index $$$p$$$ results in all $$$f_g(b, i) \le 1$$$. Equivalently, the indices $$$q$$$ paired with $$$p$$$ must include all indices that initially had $$$f_g(a, i) = 2$$$.
If no such removal $$$p$$$ works, Alex can achieve his goal of keeping the beauty at least $$$g$$$.
Checking each first move $$$p$$$ requires $$$\mathcal{O}(f_g(a, p))$$$ time, and summing up over $$$\sum_{1\le p\le n} f_g(a, p) \le 2(3n) = \mathcal{O}(n)$$$ since we only maintain at most three previous values of $$$a_j$$$ (for $$$j \lt i$$$) during the calculation of $$$f_g(a, i)$$$.
The total time complexity is $$$\mathcal{O}(n \log_2 10^9)$$$ since we perform a binary search over $$$g$$$ and compute $$$f_g(a, i)$$$ in linear time per iteration.
def main():
n = int(input())
arr = list(map(int,input().split()))
# calculate the number of j for each i that satisfy arr[max(i,j)] - arr[min(i,j)] >= target
def measurecount(arr,target):
m = len(arr)
count = [0]*m
minimum = []
for i in range(m):
for j in range(len(minimum)):
if minimum[j] + target <= arr[i]:
count[i] += 1
minimum.append(arr[i])
minimum.sort()
if len(minimum) > 3:
minimum.pop()
maximum = []
for i in range(m-1,-1,-1):
for j in range(len(maximum)):
if maximum[j] - target >= arr[i]:
count[i] += 1
maximum.append(arr[i])
maximum.sort(reverse=True)
if len(maximum) > 3:
maximum.pop()
return count
# binary search to judge if we can find such pair
def judge(target):
count = measurecount(arr,target)
if max(count) <= 1:
return False
pick = []
if max(count) > 2:
for i in range(n):
if count[i] > 2:
pick = [i]
break
else:
for i in range(n):
if count[i] != 2:
continue
for j in range(n):
if j==i:
pick.append(j)
elif j < i and arr[j] + target <= arr[i]:
pick.append(j)
elif j > i and arr[i] + target <= arr[j]:
pick.append(j)
break
for p in pick:
count2 = measurecount(arr[:p]+arr[p+1:], target)
if max(count2) <= 1:
return False
return True
front = -10**9 - 10
rear = 10**9 + 10
while front < rear:
mid = front + (rear-front)//2
res = judge(mid)
if res:
front = mid + 1
else:
rear = mid
ans = front - 1
print(ans)
T = int(input())
t = 1
while t <= T:
main()
t += 1
#include "bits/stdc++.h"
using namespace std;
const int MAXN = 200005;
const int INF = 1000000005;
inline int fdiv(int num, int denom) {
return num / denom - ((num ^ denom) < 0 && num % denom);
}
inline int cdiv(int num, int denom) { return fdiv(num + denom - 1, denom); }
int t;
int n;
int a[MAXN];
vector<int> adj[MAXN];
void add_edge(int u, int v) {
adj[u].push_back(v);
adj[v].push_back(u);
}
bool check(int x) {
for (int i = 1; i <= n; i++) {
adj[i].clear();
}
set<pair<int, int>> st;
for (int i = 1; i <= n; i++) {
int cnt = 0;
for (auto [prv, prv_id] : st) {
if (a[i] - prv >= x) {
add_edge(prv_id, i);
}
}
st.insert({a[i], i});
if ((int) st.size() > 3) {
st.erase(prev(st.end()));
}
}
int bad_cnt = 0;
for (int i = 1; i <= n; i++) {
if ((int)adj[i].size() >= 2) {
bad_cnt++;
}
}
for (int i = 1; i <= n; i++) {
int delta = (int)adj[i].size() >= 2;
for (int v : adj[i]) {
if (adj[v].size() == 2) {
delta++;
}
}
if (delta == bad_cnt) {
return false;
}
}
return true;
}
int main() {
cin >> t;
while (t--) {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int lo = -INF, hi = INF;
while (lo < hi) {
int mid = cdiv(lo + hi, 2);
if (check(mid)) {
lo = mid;
} else {
hi = mid - 1;
}
}
cout << lo << '\n';
}
return 0;
}
2156F1 - Strange Operation (Easy Version)
What will the first element of permutation be for the final result?
If the first element is odd, we can always reduce it to $$$1$$$, otherwise, we can always reduce it to $$$2$$$.
If the first element is even, before reducing the first element to $$$2$$$, we must reduce some element to $$$1$$$ at first. Which one to choose?
You should choose the leftmost odd elements that all elements to the left is greater than it.
Treat the rest of elements as a new permutation
Since we need to find the lexicographically smallest permutation, our goal is to make the numbers on the left as small as possible.
Suppose we have a permutation $$$[p_1, p_2, \ldots , p_n]$$$.
The first question we would like to answer is: where will the number $$$1$$$ appear in the final lexicographically smallest permutation?
Case 1: $$$p_1$$$ is odd.
In this case, the answer is straightforward — $$$p_1$$$ can always be decreased to $$$1$$$. Hence, $$$1$$$ will appear at the first position.
Case 2: $$$p_1$$$ is even.
This case is more complicated. For a number $$$p_i$$$ to be reduced to $$$1$$$, two conditions must hold:
- $$$p_i$$$ is odd.
- All numbers $$$1, 2, \ldots, p_i - 1$$$ appear to the right of index $$$i$$$.
In other words, for every $$$j \lt i$$$, we must have $$$p_j \gt p_i$$$.
We find the minimum possible index $$$i$$$ that satisfies both of the above condition, and reduce $$$p_i$$$ to $$$1$$$.
After that, since $$$p_1$$$ is even, we reduce $$$p_1$$$ to $$$2$$$.
It can be proven that choosing the smallest such index $$$i$$$ and performing these two reductions, first decreasing $$$p_i$$$ to $$$1$$$, then decreasing $$$p_1$$$ to $$$2$$$, will always yield the lexicographically smallest permutation. A formal proof will be given later.
Recursive construction:
If $$$p_1$$$ is odd, reducing $$$p_i$$$ to $$$1$$$ transforms the remaining multiset $$$[p_2, p_3, \ldots , p_n]$$$ into $$$[2, 3, \ldots, n]$$$. This can be treated as a new permutation problem of size $$$n - 1$$$.
If $$$p_1$$$ is even, after reducing $$$p_i$$$ to $$$1$$$ and $$$p_1$$$ to $$$2$$$,
the remaining multiset $$$[p_2, p_3, \ldots, p_{i-1}, p_{i+1}, \ldots, p_n]$$$ becomes $$$[3, 4, \ldots, n]$$$, which again forms a smaller permutation problem of size $$$n - 2$$$.
Thus, the process can be applied recursively.
Complexity Analysis:
The overall time complexity is $$$\mathcal{O}(n^2)$$$, which is efficient enough to pass the first subtask (F1).
Now let's prove that this solution always lead the permutation to smallest lexigraphically possible.
Suppose we have permutation $$$[p_1, p_2, \ldots, p_n]$$$
When $$$p_1$$$ is odd, the conclusion is straightforward. We can always decrease $$$p_1$$$ to $$$1$$$ and treat the remaining elements as a new permutation.
When $$$p_1$$$ is even, let $$$i$$$ be the minimum possible index such that $$$p_i$$$ can be decreased to $$$1$$$. In other words, $$$i$$$ is the smallest index such that $$$\min(p_1, p_2, \ldots, p_{i - 1}) \gt p_i$$$ and $$$p_i$$$ is odd. We need to prove that decreasing $$$p_i$$$ ($$$1 \lt i \le n$$$) to $$$1$$$ does not affect the lexicographically smallest possible prefix $$$[p_1, p_2, \ldots, p_{i-1}]$$$ that can be formed.
Transforming $$$[p_1, p_2, \ldots, p_{i-1}]$$$ into its lexicographically smallest possible form involves three types of operations. Suppose an operation chooses indices $$$x \lt y \lt z$$$ and performs the following steps: 1) item subtract $$$2$$$ from $$$p_x$$$, 2) add $$$1$$$ to $$$p_y$$$, and 3) add $$$1$$$ to $$$p_z$$$.
We analyze each possible case relative to $$$i$$$:
Case 1: $$$x \lt y \lt z \lt i$$$
- This case is trivial. Changing $$$p_i$$$ to $$$1$$$ only affects indices greater than $$$i$$$, so these operations remain completely valid.
Case 2: $$$x \lt y \lt i \lt z$$$
- Suppose $$$p_z$$$ is within the subarray $$$[p_i, \ldots, p_n]$$$. After changing $$$p_i$$$ to $$$1$$$, the element $$$p_z$$$ (or its value) still exists, perhaps at a different position, but the multiset of values in $$$[p_i, \ldots, p_n]$$$ remains unchanged. Therefore, the operation can still be performed.
Case 3: $$$x \lt i \lt y \lt z$$$
- Since the operation does not depend on the relative order or values of $$$p_y$$$ and $$$p_z$$$, and the multiset $$$[p_i, \ldots, p_n]$$$ is preserved, we can still find suitable $$$p_y$$$ and $$$p_z$$$ to perform the operation. Hence, this case also remains valid.
Case 4: $$$y = i$$$ or $$$z = i$$$
If $$$p_i \gt 1$$$, then after decreasing $$$p_i$$$ to $$$1$$$, there must exist some index $$$j \gt i$$$ such that $$$p_j$$$ equals the original value of $$$p_i$$$. Thus, the operation can still be performed using $$$p_j$$$.
If $$$p_i = 1$$$, then it is impossible for any $$$j \lt i$$$ to have $$$p_j = 1$$$, as that would violate the rule of minimality. This is precisely why we must choose the smallest possible index $$$i$$$ for which $$$p_i$$$ can be reduced to $$$1$$$; otherwise, the prefix could incorrectly contain $$$1$$$.
Therefore, if there exists a sequence of operations that transforms $$$[p_1, p_2, \ldots, p_{i-1}]$$$ into the lexicographically smallest possible prefix, none of these operations will be affected by decreasing $$$p_i$$$ to $$$1$$$ beforehand.
Hence, we can always decrease $$$p_i$$$ to $$$1$$$ without affecting the lexicographically smallest prefix.
def main():
n = int(input())
p = list(map(int,input().split()))
for i in range(n):
p[i] -= 1
seq = []
indexes = [i for i in range(n)]
def update(indexes):
count = 0
for i in range(n):
if indexes[i] < 0: continue
indexes[i] = count
count += 1
curr = 1
ans = [-1]*n
for i in range(n):
if ans[i] > 0:
continue
if indexes[p[i]] % 2 == 0:
ans[i] = curr
curr += 1
indexes[p[i]] = -1
update(indexes)
continue
prefix = p[i]
pick = -1
for j in range(i+1,n):
if ans[j] > 0:
continue
if p[j] > prefix or indexes[p[j]] % 2 > 0:
prefix = min(prefix,p[j])
continue
pick = j
break
ans[j] = curr
curr += 1
ans[i] = curr
curr += 1
indexes[p[j]] = -1
indexes[p[i]] = -1
update(indexes)
print(*ans)
T = int(input())
for _ in range(T):
main()
Each move only shuffles the triple of consecutive values $$${a,a+1,a+2}$$$ and places the smallest among them at the leftmost of the three chosen positions.
Think in terms of a value’s rank among the not-yet-fixed values: one move on a value is like moving it two places to the left in that order. A value at rank $$$r$$$ can move at most $$$\lfloor r/2\rfloor$$$ steps.
To minimize lexicographically, process positions from left to right and push the current choice as far left as allowed. Parity matters: when the current rank is odd, you must “pair” with a smaller value to make the plan realizable.
We want the lexicographically smallest permutation reachable by the triple move. Focus on the first position :
- If the first value is odd, we can keep applying moves that reduce it by $$$2$$$ until it becomes $$$1$$$.
- If it is even, we can keep reducing by $$$2$$$ until it becomes $$$2$$$.
Why? Each move that subtracts $$$2$$$ from some position $$$i$$$ uses two positions $$$j,k$$$ to its right that currently hold the two consecutive values just below it. In a permutation these exist until you reach $$$1$$$ (odd start) or $$$2$$$ (even start). Using them only increases those right-side values by $$$1$$$, so they never block making the first value as small as parity allows.
Now suppose the first value is even and we set it to $$$2$$$. The next question is: where should $$$1$$$ go? The correct choice is the leftmost value that can be reduced to $$$1$$$.
Two simple facts characterize when a value $$$v$$$ can be reduced to a target $$$cnt$$$:
- Parity: moves change a value by $$$\pm 2$$$ overall, so $$$v \equiv cnt \pmod 2$$$ is necessary.
- No smaller blockers to the left: to reduce $$$v$$$ down step by step, for each intermediate step you must pick the pair $$${x,x+1}$$$ with $$$x \in {cnt,cnt+1,\dots,v-1}$$$ to the right of $$$v$$$. So $$$v$$$ must lie to the left of all values in $$$[cnt, v-1]$$$.
This gives a clean greedy: at step $$$cnt=1,2,\dots,n$$$, among values $$$i\in[cnt\ldots n]$$$, scan by increasing $$$i$$$ and keep the running minimum position seen so far. Every time that minimum improves (a “record minimum”), if $$$i \equiv cnt \pmod 2$$$ then value $$$i$$$ is feasible to reduce to $$$cnt$$$; among all feasible ones, the final record minimum is leftmost and is the one we must take.
Why lexicographically optimal? The array first differs where we place $$$cnt$$$. Picking the leftmost feasible position ensures the smallest possible number at that index. Any alternative that puts $$$cnt$$$ strictly to the right makes the prefix strictly larger and cannot be beaten later.
After choosing the index cur where we install $$$cnt$$$, we conceptually “pull down” the current value $$$val=p[cur]$$$ to $$$cnt$$$ by a chain of moves. Each such move also raises exactly one of the values in $$${cnt,\ldots,val-1}$$$ by $$$1$$$. Over the whole chain, every number in $$${cnt,\dots,val-1}$$$ gets raised exactly once. So, in one shot, we can set $$$p[cur]=cnt$$$ and increase all values in $$$[cnt \ldots val-1]$$$ by $$$1$$$. The remaining numbers still form a permutation of $$${cnt+1,\dots,n}$$$, and we repeat with $$$cnt+1$$$.
Because each step is just a linear scan over values and a few local updates, this runs in $$$\mathcal{O}(n^2)$$$ per test.
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <tuple>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <functional>
#include <cassert>
#include <immintrin.h>
using namespace std;
#define int long long
int p[100005];
int pos[100005];
signed main()
{
#if _LOCAL_
freopen("case.txt", "r", stdin);
#endif
int t;
cin >> t;
while(t--) {
int n;
cin >> n;
for(int i = 0; i < n; ++i) {
cin >> p[i];
}
for(int i = 0; i < n; ++i) {
pos[p[i]] = i;
}
for(int cnt = 1; cnt <= n; ++cnt) {
int cur = n;
for(int i = cnt, mn = n; i <= n; ++i) {
if(pos[i] < mn) {
mn = pos[i];
if((i & 1) == (cnt & 1)) {
cur = pos[i];
}
}
}
int val = p[cur];
p[cur] = cnt;
for(int i = cnt; i < val; ++i) {
p[pos[i]]++;
}
for(int i = val; i > cnt; --i) {
pos[i] = pos[i-1];
}
pos[cnt] = cur;
}
for(int i = 0; i < n; ++i) {
cout << p[i] << ' ';
}
cout << endl;
}
return 0;
}
A move is only possible on three consecutive values: there must exist an $$$m$$$ such that the values involved are exactly $$${m,m+1,m+2}$$$ at indices $$$i\lt j\lt k$$$.
$$$p_i=\max(p_j,p_k)+1$$$ and $$$p_i=\min(p_j,p_k)+2$$$
Those equations force the three values to be consecutive and the largest to sit at the leftmost index, which is exactly $$$c\lt \min(a,b)$$$ with values $$${m,m+1,m+2}$$$.
Each move strictly decreases lexicographic order: the first changed index is $$$i=c$$$, whose value drops from $$$m+2$$$ to $$$m$$$; earlier indices remain unchanged.
Each move removes at least two inversions among the triple (and never adds inversions before $$$i$$$), so the process is acyclic and must terminate.
Number of operations is $$$\le \mathcal{O}(n^2)$$$ (each removes $$$\ge2$$$ inversions). The pointer-walk advances by $$$+1$$$ when no operations, and jumps back by at most $$$2$$$ per op. Total steps are $$$\mathcal{O}(n+\text{ops})=\mathcal{O}(n^2)$$$ overall.
Please Read Hints
Maintain $$$pos[v]$$$. Iterate $$$m$$$ from $$$0$$$ to $$$n-3$$$:
- Let
If $$$c\lt \min(a,b)$$$, apply the operation on indices $$${a,b,c}$$$:
- Set $$$i=c$$$, $$$j=\min(a,b)$$$, $$$k=\max(a,b)$$$.
- If $$$a\lt b$$$, write $$$(m,m+1,m+2)$$$ to $$$(i,j,k)$$$ and set $$$(pos[m],pos[m+1],pos[m+2])=(i,j,k)$$$.
- Else write $$$(m,m+2,m+1)$$$ to $$$(i,j,k)$$$ and set $$$(pos[m],pos[m+2],pos[m+1])=(i,j,k)$$$.
- Then set $$$m\leftarrow\max(m-2,0)$$$.
- Otherwise, set $$$m\leftarrow m+1$$$.
This process terminates when $$$m=n-2$$$, at which point every triple satisfies $$$pos[m+2]\ge\min(pos[m],pos[m+1])$$$, so no legal move exists anywhere. Because each step is lexicographically decreasing (when an operation is performed) and the space of permutations is finite and acyclic under these moves, the result is the lexicographically smallest reachable permutation. The pointer-walk guarantees total time $$$\mathcal{O}(n^2)$$$.
Challenge: Can you prove the solution?
for _ in range(int(input())):
n=int(input())
p=list(map(int,input().split()))
pos=[0]*n
for i in range(n):
pos[p[i]-1]=i
ch=1
while ch:
ch=0
for m in range(n-2):
a,b,c=pos[m],pos[m+1],pos[m+2]
if(c<min(a,b)):
i=c
if(a<b):
j,k=a,b
p[i],p[j],p[k]=m+1,m+2,m+3
pos[m],pos[m+1],pos[m+2]=i,j,k
else:
j,k=b,a
p[i],p[j],p[k]=m+1,m+3,m+2
pos[m],pos[m+2],pos[m+1]=i,j,k
ch=1
print(*p)
2156F2 - Strange Operation (Hard Version)
Suppose the operation changes indices $$$i, j, k$$$, other than $$$i$$$, all the other indices relative position doesn't change.
Use segment tree and fenwick tree
Iterate from $$$1$$$ to $$$n$$$, during the $$$t$$$-th iteration, find the leftmost element that can be decreased by $$$t$$$.
Acclerate the procedure by finding next smaller element.
You should Read Editorial of F1 First
Let the initial permutation be $$$p=(p_1,p_2,\dots,p_n)$$$, and let the final array be $$$q=(q_1,q_2,\dots,q_n)$$$. Initialize $$$q_i=0$$$ for all $$$i$$$, meaning every position in the output is still undetermined. During the $$$t$$$-th iteration, find the smallest index $$$i$$$ whose value can be decreased to $$$t$$$. Repeatedly choose this $$$i$$$, locate indices $$$j,k$$$ such that $$$p_i=\max(p_j,p_k)+1$$$ and $$$p_i=\min(p_j,p_k)+2$$$, and perform the updates $$$p_i\leftarrow p_i-2$$$, $$$p_j\leftarrow p_j+1$$$, $$$p_k\leftarrow p_k+1$$$. This is equivalent to removing $$$p_i$$$ and setting $$$q_i\gets t$$$. After removing $$$p_i$$$, the remaining elements $$$p_1,\dots,p_{i-1},p_{i+1},\dots,p_n$$$ close the gap (preserving relative order), forming a permutation of length $$$n-1$$$.
This remove-and-assign simulation can be supported by a Fenwick tree or a segment tree so that each update and query runs in $$$\mathcal{O}(\log n)$$$ time; however, naively finding the correct index $$$i$$$ could still cost $$$\mathcal{O}(n)$$$ per step. Define the rank of $$$p_i$$$ as the number of alive (not yet removed) elements that are not greater than $$$p_i$$$, including $$$p_i$$$ itself.
To speed up the process, keep a pointer at the smallest alive index $$$i$$$ and check its rank. If the rank is odd, remove this element immediately. If the rank is even, move the pointer to the next smaller element to its right, that is, to the smallest $$$ j \gt i$$$ with $$$p_j \lt p_i$$$. Continue until you reach an element with odd rank.
Although a single "move to the next smaller on the right" step may look linear, the total number of such moves over the whole algorithm is at most $$$2n$$$. If an element is first visited when its rank is even, after some element to its right is removed, its rank becomes odd the next time it is visited; if an element’s rank is already odd, it is removed immediately upon visit. Therefore each index is visited at most twice.
To implement this, we maintain two data structures:
A Fenwick tree over values, where a $$$1$$$ at position $$$p_i$$$ indicates that the value $$$p_i$$$ is still alive (and $$$0$$$ otherwise). This lets you query the current rank of $$$p_i$$$ in $$$\mathcal{O}(\log n)$$$ time.
Let $$$ip$$$ denote the array that is the inverse of $$$p$$$, i.e., $$$ip_{p_i} = i$$$. Store a range-min segment tree over the array $$$ip$$$ . When the value $$$p_i$$$ is removed, set $$$ip_{p_i}=\infty$$$. If the current visited index is $$$i$$$, then a range-min query on $$$[1,p_i-1]$$$ returns the minimum position $$$j$$$ such that $$$j \gt i$$$ and $$$p_j \lt p_i$$$ (the next smaller element on the right by value). Each query and update costs $$$\mathcal{O}(\log n)$$$, and each index is examined at most twice, so the overall complexity is $$$\mathcal{O}(n\log n)$$$, which is sufficient for the F2 constraints.
inf = 10**9
class fenwick(object):
def __init__(self, n):
self.n = n
self.cul = [0]*n
self.maxd = len(bin(n))-3
def update(self,index,diff):
i = index
while i<self.n:
self.cul[i] += diff
i += (i+1)&(-i-1)
def getaccu(self,index):
output = 0
i = index
while i>=0:
output += self.cul[i]
i -= (i+1)&(-i-1)
return output
class segment_tree(object):
def merge(self,num,accu):
return min(accu,num)
def __init__(self,n,initial):
self.n = n
self.inf = inf
self.arr = [self.inf]*(2*n)
for i in range(2*n-1,0,-1):
if i>=n: self.arr[i] = initial[i-n]
else: self.arr[i] = self.merge(self.arr[2*i],self.arr[2*i+1])
def update(self,index,target):
index += self.n
self.arr[index] = target
while index > 0:
if index & 1:
nexttarget = self.merge( self.arr[index], self.arr[index-1])
else:
nexttarget = self.merge( self.arr[index], self.arr[index+1])
self.arr[index>>1] = nexttarget
index = index >> 1
def addnum(self,index,diff):
self.update(index, self.arr[index+self.n] + diff)
def query(self,left,right):
i,j = self.n+left, self.n+right+1
output = self.inf # initial output should be changed if you want to change the merge function
while i<j:
if i&1:
output = self.merge(self.arr[i],output)
i += 1
if j&1:
j -= 1
output = self.merge(self.arr[j],output)
i = i >> 1
j = j >> 1
return output
def main(t):
n = int(input())
p = list(map(int,input().split()))
location = [0]*n
for i in range(n):
p[i] -= 1
location[p[i]] = i
seg = segment_tree(n, location)
fen = fenwick(n)
for i in range(n):
fen.update(i,1)
ans = [-1]*n
curr = 1
for i in range(n):
if ans[i] >= 0:
continue
index = fen.getaccu(p[i]) - 1
if index % 2 == 0:
fen.update(p[i],-1)
seg.update(p[i],inf)
ans[i] = curr
curr += 1
continue
j = i
while True:
j = seg.query(0,p[j]-1)
nextindex = fen.getaccu(p[j]) - 1
if nextindex % 2 > 0:
continue
break
ans[j] = curr
ans[i] = curr + 1
curr += 2
seg.update(p[i],inf)
seg.update(p[j],inf)
fen.update(p[i],-1)
fen.update(p[j],-1)
print(*ans)
T = int(input())
for t in range(T):
main(t)








Auto comment: topic has been updated by MathModel (previous revision, new revision, compare).
what is the point of system testing $$$A-D$$$ if the pretests are the same as the sys tests?
also, nice leetcode reference in $$$E$$$
isn't the pretests don't contain all the tests?
they tried something different for hacks/systests this round (see the announcement here: https://codeforces.me/contest/2156)
how you guys find that [2*i,3*i,4*i] thing in C during contest? still cant arrive at that.
for a number greater than equal to 4i ( say q*i + r, where q>=4, 0<=r<i ) split to i,i+r,(q-2)*i and so i+r will be removed ( holding the inequality i <= i+r < (q-2)*i )
if a number is less than 4*i then you cant split it such that their gcd will be i so the number themselves have to be divisible by i
thank you, the derivation is nice, i stressed myself making the third element in the split also a multiple of x which was the mistake i made.
i solved it with this intuition
https://codeforces.me/contest/2156/submission/345624043
Have you been able to come up with this on live contest ??? or is it a trick you have seen previously in other problems ???
Actually up to 3*i is enough, for the numbers >= 4*i you can apply split. How to come up to than, just try to be greedy and find max amount of numbers that you can use split.
upto 3i is not enough
how will you split if it is 3i+1
I meant divisors
like let us say , take a number a = 2*i and we wanna make i as the gcd . so 2i is already a good element and then , let us say 2i+1 , how do we split it? i guess we can do it by i , i and 1 which satisfies 1<=i<=i , similarly upto 3i we can make the split like i , i and r where 1<=r<=i-1. and then 3i is also a good element , now how do we split 3i+1 ? i , 2i , 1 , where 1<=i<2i , similarly we'll be keep doing this upto 4i and will split it like , i , 2i and r where 1<=r<=i-1 and we will always remove r. According to this numbers >=2i are always good , but i think in editorial it is not the case... so where am i wrong ? //UPDATE
i got it i can only remove x2 , but i was removing x1 always , sorry for the rookie doubts..
if g is the gcd you are considering: a number x which is n*g + r can always be split to g, g+r, (n-2)*g, but for g<g+r<(n-2)*g to hold, the number should be at least 4*g so we can split it to g,g+r,2*g otherwise it wont hold
i used binary search for A :( and Good B
hey, can you share the code for binary search for the first problem? thanks!
https://codeforces.me/contest/2156/submission/345700558
Auto comment: topic has been updated by maomao90 (previous revision, new revision, compare).
Auto comment: topic has been updated by maomao90 (previous revision, new revision, compare).
Why Binary search is required for E — Hint 1.2 version ? (easier version where Alex moves first ? ).
Can't we just maintain two values for each index... primaryMin,secondaryMin on prefix,,, and primaryMax,secondaryMax in suffix.
Now, we assume, we are locking current index
ias our first index (As alex)... so in next move Hao will try to delete primaryMax on right(suffix), or primaryMin on left(prefix), and we might get answer in O (N). ( loopifrom 1 to N ). We will pick the index, which gives highest return.Anything wrong with this approach ??????
cc : Editorialists ( maomao90 , MathModel ).
You can do it without binary search (which I did), although it takes a bit more work :
For each index $$$i$$$, find the 3 best targets $$$j_1, j_2, j_3$$$, which give results $$$a_1 \geqslant a_2 \geqslant a_3$$$. Now if Hao wants to deny the result $$$a_3$$$, he can only do so by removing $$$i$$$ in the first move. If he want to deny $$$a_2$$$, he can do so only by removing either $$$i$$$ or one of $$$j_1, j_2$$$ in the first move. He can always deny $$$a_1$$$.
So sort all events (value, list of possible cuts) by decreasing value, and find the cut which is contained in the maximum prefix of such events by merging the lists.
You still end up with $$$O(n log(n))$$$ though since you need the sort.
Actually, you could do O(n), though it is not much faster since it has high constant factor. 346744557
For A problem the first approach of (n-1)//2 wont it fail for many testcases like say 13 which should give optimal answer to be 5 but this code gives 6...someone pls help me out here.
The process goes as following :
So Hao eats $$$6$$$ pieces not $$$5$$$ as you claim.
ohh thank you so much
(13-1)/2 is 6 only
FAST EDITORIAL! Thanks for the contest :)
C was one heck of a question.
Spent 1.5hrs on that and still not able to solve.
first, you need to establish a logic that... any number(N) can be represented (splitted into three parts) for base(x), if that N >= 4*x.
Suppose N > 4*x for now. (N == 4*x is very obvious split (x,x,2x))
imagine M = N / x , L = (N % x) , mathematically L < x ( remainder is always lesser than divisor).
So, we can represent N = (x) + ((x + L)) + ((M-2) *x).
Try for any value.
Once you have established above logic, its just frequency counting question... keeping suffix sum is sufficient to solve...
thanks
thanks for quick editorial
i had correct idea of D .. but had
nin the formula instead ofn-1by mistake.. so couldn't prove it will be< 2n... noooo !!!how do you prove that please help me
I really liked the problem C. worth solving!
Problem C is beautiful. Thanks for the quick editorial!
Loved the problem C :3
Very detailed editorial with step-by-step approach to the solutions. This is very helpful for beginners.
Fast editorial forces:)
Thanks for the super great editorial ! wasn't able to solve B in the contest, but the editorial really helped me understand the approach well ! :)
Nice editorial :)
loved problem B
I'll write another greedy for F1, which can be seen as a proof for the Bonus solution :
Consider the smallest $$$i$$$ that can be changed, that is $$$i$$$ appears before $$$i - 1$$$ and $$$i - 2$$$. Then doing the move from $$$i$$$ decreases lexicographically the permutation, but also makes any move from $$$j \gt i$$$ easier (if $$$j \gt i + 2$$$ then nothing changes, for $$$j = i + 2$$$, $$$i$$$ is pushed to the right, and for $$$j = i + 1$$$ the min of $$$i - 1$$$ and $$$i$$$ is pushed to the right).
Hence there is no good reason not to do this move, so do it and start again until there are no moves left. Alternatively, it is equivalent to reducing taking the position of $$$3$$$ and reducing it as far as you can, then the position of $$$4$$$ and reducing it as far as you can, etc...)
You can also adapt this solution with a Treap (on the inverse permutation) to pass F2, see my submission
I don't understand how this is proof at all. I agree that applying the operation on $$$i$$$ doesn't make any other operation $$$j \gt i$$$ invalid, but how does that imply that performing $$$j$$$ first doesn't result in something lexicographically smaller?
I'll give three proofs :
1 : proof by AC submission
2 : proof left to the reader
3 : let's denote by $$$(i, j)$$$ the operation on position $$$i$$$ when $$$p[i] = j$$$, and consider some optimal sequence of operations $$$(i_k, j_k)$$$. If there exists some $$$(i_1, j_1)$$$, $$$(i_2, j_2)$$$ one after the other such that $$$i_2 \ne i_1$$$ and $$$j_2 \leqslant j_1$$$, we can swap the two operations since actually we must have $$$j_2 \ne j_1$$$, $$$j_2 \ne j_1 - 1$$$ since $$$j_1 - 2$$$ was placed before them, so the two operations are disjoint.
Hence by noting $$$(i, j \rightarrow j')$$$ some sequence $$$(i, j), (i, j - 2), \ldots, (i, j' + 2)$$$, there exists some optimal sequence of operations of the form $$$(i_1, 1 \rightarrow v_1), (i_2, 2 \rightarrow v_2), \ldots, (i_n, n \rightarrow v_n)$$$
Now for such a sequence, if some $$$(i, j)$$$ is not reduced as much as it could, reducing it further only makes subsequent reducing easier (this is in essence my discussion above, since every subsequent value must be to the left of all values it skips on the way down), hence reducing each value as much as you can is optimal (any reduction at position $$$i' \lt i$$$ will still happen, so the prefix stays the same and the value at position $$$i$$$ decreases).
Is this proof correct? Lemma 1:- A operation decreases number of inversions in the permutation by 2
Lemma 2: Applying operation on increasing order of values will never kill a operation that I could have done before of doing this while the inverse is not true.
Now, As each operation decreases my no. of inversion by 2. if we could maximize the number of operation that we could do we are bound to achieve the lower bound in number of inversions which will give the lexicographically minimal.
Minimizing the number of inversions doesn't necessarily yield the lexicographically minimal permutation, $$$[1, 5, 4, 3, 2]$$$ has more inversions than $$$[2, 1, 3, 4, 5]$$$ while being smaller.
And since swapping two operations actually changes the resulting permutation, you still need to show that it is optimal to do them in increasing order, which is what I clarified above .(Also you have to allow applying $$$i$$$, then $$$i - 2$$$, then $$$i - 4$$$, etc in order from the same position, so it cannot be all increasing)
Wow, the first part is quite nice, thanks for the proof!
great proof, i think the only flow in your earlier proof was not considering making an operation on a larger value that could later help smaller values but the second paragraph in the second proof clears everything.
But my question to you is how do you sort this sequence (i1, 10), (i2, 11), (i2, 9), (i2, 7), (i2, 5), (i1, 8)
"there existing an optimal sequence of moves in the form of blocks" is indeed true as its a weaker form of the constructive solution, but i dont think what you provided is enough to say that any optimal solution can be sorted down to a sequence of blocks
The assumption in the sequence you gave is that $$$8$$$ is in position $$$i_1$$$, then the operation $$$(i_2, 9)$$$ puts $$$7$$$ in $$$i_1$$$ where $$$8$$$ was, so the operation $$$(i_1, 8)$$$ doesn't exist.
I agree that my proof was evasive, but if you think about swapping an operation with a whole block, you can use the same casework to see that for both operations to be valid, they have to be disjoint and the swap is valid
Can anyone give me some methods how to approach the problem C?
Suppose we want a number 'X' to be the answer then either all the numbers should be divisible by 'X' or we are able to break down these numbers into multiples of X, then only it can be our answer.
First observation is that firstly remove all the numbers < X, as if any of them are present then "X" can't be the answer. Hence, if you have 'Y' numbers < 'X', then apply 'K' operations to remove them . If 'K' < 'Y', then no matter what you do you can't remove all numbers < X, so it can never be the answer.
Second observation is that, after trying out few examples you will see that if you want to break a number 'Y' into multiple 'X' then it should be at least 4*X.
PROOF :
For a number 'Y' which is not divisible by 'X', then for it to be converted into a multiple of 'X' you want it to break such that the non-multiple multiple part of 'Y' is in the middle. Hence, one possible greedy construction :
First part = 'X' (smallest)
Second part = 'X' + non-divisible part (second largest)
Third part = multiple of 'X' >= second part (largest part)
Looking at this gives us that the third part would be bare minimum 2*X, as second part is always greater than 'X' so, the nearest multiple divisible by 'X' and greater than 2nd part, would be 2*X.
SO, summing these up gives : X + (X + non-divisible part) + 2*X, which is gives us a lower bound of 4*X.
Hence, we don't care about any number >= 4*X, as, we can always make them divisible by 'X'. So, we are left with numbers smaller < 4*X, as we can't change them, only option left with us is to delete non-divisible ones. Hence, we check that if remaining numbers other than the ones >= 4*X, and also, multiples of 'X' less than 4*X, i.e. freq[X] + freq[2*X] + freq[3*X], are <= 'K' or not. If YES then this 'X' can be our answer else it can't be.
Here's my code. Hope this helps!
bro why it should not be 3X , why it would be 4X always
Suppose we have a number
Ysuch that3*X < Y < 4*Xi.e. $$$Y \bmod X \ne 0$$$.Now, if we try to partition it into three parts such that $$$Y = Y_1 + Y_2 + Y_3$$$ and $$$Y_1 \le Y_2 \le Y_3$$$, then we must make sure that both $$$Y_1$$$ and $$$Y_3$$$ are multiples of $$$X$$$, which obviously leaves the middle part $$$Y_2$$$ with the non-divisible remainder (since $$$Y$$$ itself isn’t divisible by $$$X$$$).
REMEMBER : We want multiples of $$$X$$$ at both the end, hence $$$Y_1$$$ and $$$Y_3$$$ must be multiples of $$$X$$$
So, we first assign the lowest possible multiple of $$$X$$$ at the start: $$$Y_1 = X$$$. This leaves us with the remaining part : $$$Y - X \in (2X, 3X)$$$.
Now, let the remainder $$$R = Y \bmod X$$$. We’ll have the non-divisible part (the remainder) somewhere inside (in the middle). But leaving it alone would make it smaller than $$$Y_1$$$, since any remainder is always less than the divisor ($$$R \lt X$$$). Hence, $$$Y_2 = R$$$ would violate the condition $$$Y_2 \ge Y_1$$$. So, we must increase $$$Y_2$$$ without affecting the multiplicity of $$$Y_1$$$ and $$$Y_3$$$. The only simple way to do that is to add another $$$X$$$ to it i.e. $$$Y_2 = X + R$$$.
Now, the last part becomes:
$$$Y_3 = Y - Y_1 - Y_2$$$
$$$Y_3 = Y - X - (X + R)$$$
$$$Y_3 = Y - 2X - R$$$
Since, we assumed $$$Y \in (3X, 4X)$$$, this means now, $$$Y_3 \lt 4X - 2X - R \lt 2X - R$$$.
But $$$Y_2 = X + R$$$, and because $$$R \gt 0$$$, we get $$$Y_2 \gt X$$$. But having $$$Y_3 \lt Y_2$$$ is a violation, breaking the original order of $$$Y_1 \le Y_2 \le Y_3$$$.
Hence, for any $$$Y \lt 4X$$$, such a valid partition is IMPOSSIBLE!.
Now, if $$$Y \ge 4X$$$, we can take :
$$$Y_1 = X$$$, $$$Y_2 = X + R$$$, and $$$Y_3 = Y - 2X - R$$$.
Here $$$Y_3 \ge 2X$$$, so the ordering holds ($$$Y_1 \le Y_2 \le Y_3$$$), and both $$$Y_1$$$ and $$$Y_3$$$ are multiples of $$$X$$$.
Hence, the minimum threshold for proper division of $$$Y$$$ into $$$Y_1, Y_2$$$, and $$$Y_3$$$ is
Y >= 4*X.You may try out few examples yourself to see it more clearly!
Hope this helped :)
great explanation actually
I managed to squeeze some lame recursive brute-force in F1 lol 345611854
Hey in F1, Can you please clarify me! Is reducing the odd first before the even is not same as reducing the minimum (which is satisfying the conditions)? My submission 345616139
It was a great contest.
Till this date, I was wrong about the sum of
(n + n / 2 + n / 4 + n / 8 + ... ), which is actually2n. I thought this series is same as(n + n / 2 + n / 3 + n / 4 + ...)which isnlog(n). So I missed the simple solution of problem D.You're mixing between :
and
The first can be obtained with G.P sums to end up with $$$2n$$$
the second is obviously less , since either of the following cases will happen :
$$$n$$$ is a power of two , hence the sum will be $$$n+\frac{n}{2}+\frac{n}{4}+...+1=2n-1$$$
there exists a power of two $$$j$$$ such that $$$n \bmod 2^j \neq 0$$$ so the sum will be off by at least two (i.e. $$$ \lt 2n-1$$$).
Thus in all cases the sum will be $$$ \lt 2n$$$.
but in the case where its ceil(n/2^i), the sum can be larger than 2*n. Thus the editorial for D is incorrect. When you plug in the value 34 for the formula in hint 3, you get 69 which is not <= 2*34. So for some values of n, the editorial solution exceeds the query limit.
uh , It's floor not ceil though and floor $$$\le$$$ ceil , obviously in our case it's $$$ \lt $$$
if we took your example ,
so we've
so it still holds.
Maybe we're talking about different problems? Im talking about 2156D — Find the Last Number Hint 3 clearly displays a sum of ceilings. Plug in n = 34 into hint 3 for 2156D and its clear the hint (and thus the solution) are incorrect. Maybe im missing something?
Just a small typo in Bonus solution of Problem B, if si = 'B' perform ai = ai/2^min(x,y) there instead of Logn it should be Log(ai).
I upsolved F1 and I found it easier than D. I wish I had seen it in contest. Wasted my time in D.
Can anyone help me spot out edge case for my code, it fails at test-5
Linked every number with its factor (only till its 3rd multiple) using sieve, Computed frequency for every factor, For each factor (x) used binary search to count number of elements >= 4*x
It is possible to solve E in
O(n).We also need to make an observation that the maximum value will be achieved on the 4-th move.
Just like in the editorial let's first consider a game where Alex goes first. Now the game is reduced to one move by Alex, one block by Hao, and final move by Alex. Let's compute the value for each index
ithat Alex will take on the first move. To do that we need to know 2 smallest values for allj < iand 2 largest values forj > i. This can be easily done inO(n), we will also need to store the indices of largest and smallest values.Now for each
iwe compute an array of possible second moves. This will be up to 4 possible moves. We know that Hao will remove the largest element from the list, so the answer is the second largest.Now we know what will be the answer if Alex started. But we know that Hao is starting and it is optimal for him to disturb Alex'es best move. This can happen if Hao removes best starting move for Alex, or one of 4 possible values that Alex would take on 2nd move.
So we solve the problem again with 5 possible elements removed. Each Alex starting solution takes
O(n)time and will be done at most 6 times. 345606017Yes you are right, one of the tester has discovered that this problem can be solved by O(n) and even python only used 600ms. However since E is already too hard, and we just set n=10^5 to only make O(n^2) fail.
orz
For E, Can anyone please tell me how the following case is covered in the author's implementation where exactly one index has adj[i].size() > 2. for that i, Let say it has 5 children, with 2 children having degree = 2 and 3 children having degree = 1. But we only added the edge for 3 children which can be all of those which had degree = 1, in that case when we remove the index "i", according to the code we were not able to cover all 2 degrees but in reality we did removed all 2 degrees. How is that case being covered i cant understand
Isn't F1 too easy given its position and points.
$$$E$$$ $$$ \gt $$$ $$$D$$$ $$$ \gt $$$ $$$F1$$$
It isn't!
Actually all testers virtual participate my round and only two VIP testers (around 3000 rating) solve F1. All the other testers including several red testers who has around 2600 rating failed to solve F1. So we thought F1 may be very hard and must have a difficulty of at least 2600, so we set F1 as 3250. However nearly 470 contestants solved F1 during contest, which were greatly beyond our expectations.
I think it is because of the use of LLMs, really we can't judge the rating of problem now a days as it is possible a problem may be tough but easy for LLMS hence more solves and vice-versa
Also, say one person solved a problem in a group of 5, with helps of LLM they can make sufficient changes in code to avoid plagiarism and within the contest time
On my first read I too found F1 < D, but couldn't implement it perfectly which can be avoided. It really sucks...
some platform coordinators require us problem setters to create problems that 1600 rating user can solve but even highest LLM cannot solve, which is nearly impossible today.
As a participant, the problem C was fantastic! It really took me time to find out the conclusion and solve it. Good contest and tutorial!
Can someone please explain why my code is correct? I’m a bit unsure after reading the editorial. My approach was to count how many times a number x appears on the left side and check whether the number on the right side is greater than x. I also attempted to remove k elements for a specific index i. Problem(C) https://codeforces.me/contest/2156/submission/345630175
Is it just me, or is C harder than D?
Me too
can anyone please make me understand the optimisation in the problem B, because the method i did was correct but i was getting TLE on that.
Here is my solution- https://codeforces.me/contest/2156/submission/345585986
TRY CASE : AAAAAAAAAAAAAAAAAAAA(20 times) and n = 1e9
Suppose s is all 'A' and on the i-th query, a[i]=1e9, you will run 1e9 times. The slight difference of your code and the tutorial is that it considers all-'A' case.
You need to handle separately the case where the string consists entirely of A’s, as that case is causing the TLE.
Thanks for the advice,i've printed the whole query as it is when string contains all the A's.
W editorial
Who is Katrina?
C was such a nice problem, ive nver seen one like it
Can any one help in getting intuition for the problem C ?
Check this, maybe this might help.
sushant4599, thanks for your help !
In the bonus solution of B , i am not able to understand why there's a
log^2factor in it's time complexity instead oflog??345718528
Could someone explain why this is incorrect?
can someone help me out with C: in the solution given , i dont know how he calculated the part not divisible by g , part he only find count greator than 4g what about divisibility part ? can anyone help me out ? here i did with brute force , finding both >4*i and numbers not divisible by i ( that can be relieved) i did brute force edit: understood
That was an amazing competition!
There's probably a typo in hint 3 of task E. Or maybe I misunderstood something?
we need $$$f_g(a,i)≥2$$$ instead of $$$f_g(a,i) \gt 2$$$
Guys would this solution still be efficient even if n<=10^5?
Yes , It's actually the bonus solution , your solution is $$$\mathcal{O}(n \log(10^9))$$$
Ah,I see.
Anyone solved problem-D using XOR properties?
F1 is so ez!
just go from x = 3 to n, and if(index[x] < idx[x-1] && index[x] < idx[x-2]) make the operation, because it always optimal.
and just make this loop n more times.
I have an alternative solution for problem E.
The answer for the problem can be determined within the first $$$4$$$ moves.
Compute $$$f_{j}$$$ as the maximum beauty of the array when Hao chooses index $$$j$$$ as his first move. The answer is then $$$\min\limits_{1\leq j\leq n}(f_{j})$$$.
Read the hints, our goal is to compute $$$f_{j}$$$.
Fix an index $$$i$$$ as Alex's first move (in the second turn), and define:
The reason for choosing a triplet will be explained shortly. Let $$$val_{j}$$$ denotes the beauty for index $$$j$$$, defined as $$$val_{j} = a_{i} - a_{j}$$$ for $$$j \lt i$$$ and $$$val_{j} = a_{j} - a_{i}$$$ for $$$i \lt j$$$.
In some cases (such as $$$i = 1$$$), some indices may not exist. However, without loss of generality, assume that all $$$6$$$ indices are valid. Now consider:
These are the $$$6$$$ best choices for Alex in his fourth turn. Before that, Hao has $$$2$$$ turns to eliminate $$$2$$$ numbers. Since he wants to minimize the beauty, he will eliminate the $$$2$$$ largest values.
Sort the above values in descending order. Let $$$x_1$$$, $$$x_{2}$$$, and $$$x_{3}$$$ be the indices corresponding to the $$$3$$$ largest values (where each $$$x_k \in {l_{1}, l_{2}, l_{3}, r_{1}, r_{2}, r_{3}}$$$). The reason for choosing a triplet is to guarantee that $$$x_{1}$$$, $$$x_{2}$$$, and $$$x_{3}$$$ exist.
Let us analyze how this affects $$$f_{j}$$$ by considering $$$j$$$ as Hao's first move.
Case 1: $$$j = i$$$
This is invalid since $$$i$$$ is Alex's first move, so $$$f_{i}$$$ remains unchanged.
Case 2: $$$j = x_{1}$$$ or $$$j = x_{2}$$$
In this case, Hao's first move eliminates either $$$x_{1}$$$ or $$$x_{2}$$$. Therefore, after $$$2$$$ moves (first and third turns), both $$$a_{x_{1}}$$$ and $$$a_{x_{2}}$$$ are eliminated, leaving the maximum beauty for Alex as $$$val_{x_{3}}$$$.
Thus, we update $$$f_{x_{1}} = \max(f_{x_{1}}, val_{x_{3}})$$$ and $$$f_{x_{2}} = \max(f_{x_{2}}, val_{x_{3}})$$$.
Case 3: $$$j \neq i$$$, $$$j \neq x_{1}$$$, and $$$j \neq x_{2}$$$
In this case, Hao's first move does not remove either $$$x_{1}$$$ or $$$x_{2}$$$. Therefore, in his third turn, he will remove $$$x_{1}$$$ since it has the maximum value. Consequently, Alex will select $$$a_{x_{2}}$$$ in his fourth turn, giving a maximum beauty of $$$val_{x_{2}}$$$.
Therefore, we update $$$f_{j} = \max(f_{j}, val_{x_{2}})$$$ for all $$$j$$$ satisfying this case.
I used a Lazy Segment Tree to handle Case 3. If anyone has a more optimal approach, please tell me.
My implementation: 345835104
Are the solutions written by different people? I noticed that the solutions use different languages, and even for solutions in the same language, there are variations in coding styles. Some of the code styles are just too hard to ignore and I can't help but complain... Take the C problem, for example. Isn't the code a bit too compact? Where are the indentation and spacing? I know that seeking standardized coding styles in OI might seem a bit strange, but what on earth is #define int long long? Should this appear in a proper solution?
Late to the party but can someone explain the solution of D. I got the gist of the solution but unable to understand 3rd and 4th paragraph of the editorial given. Why do we discard the elements that had different bits in the previous calculation?
Okay I got this. Also the editorial's 3rd and 4th paragraph could have been made a lot simpler rather than just confusing math. The thing is you filter out the numbers that have different last bit because they can't be the last Pn number because at least one bit is different. We will follow this approach till the highest bit and generate the number.
C, D were very interesting questions. xd
Can you explain B problem? How to escape tle?
Every problem A-D except for B was pretty nice. Btw my n sqrt(n) solution for C passed lol
Actually, I found an
O(n)approach for problem E. First, we need to observe that the optimal answer can be achieved in no more than 4 moves. DefineF(x, y)=b[max(x, y)] - b[min(x, y)]. Lets just assume there was two indicesiandjwhereF(i, j)is maximized. Then, optimally, Hao would delete eitheriorjdepending on frequencies of values in these indices (we don't care about it). Let's just assumejis deleted andiis remaining. Alex will lock indexi. Next, definekas the second best index that makesF(i, k)maximized. Hao would optimally delete this index in his next move. Finally, defineqas the third index that makesF(i, q)maximized. Alex will lock this index. Then, because Alex lockediandq, our best answer depends on neither which indices Hao erases nor Alex locks.As in editorial, lets just say Hao will make the answer to be least of the answers for when Alex starts with arrays that some
xis deleted. So, lets just focus on finding that indices which are worth trying. It turns out for somexwe need two minimums in range[1, x - 1]and two maximums[x + 1, n], because Hao deletes no more than 2 elements. So, we just can precompute prefix minimums and suffix maximums, find the best index that the second best is maximized, and just try to delete this element, first minimum in range[1, x - 1], second minimum in range[1, x - 1], first maximum in range[x + 1, n]and second maximum in range[x + 1, n].Total complexity would be
O(n + 5n) = O(n). Here is my submission: 345943514Hi, Can anyone please help me find problem with my solution for D,
Submission Link: Click here
We can solve E without using binary search, here's my solution in O(n) 345998503
Problem E. For the O(n) solution of E, one just needs to look at 3 possible first moves by P1.
First solve the simple game in which P2 chooses, P1 blocks, P2 chooses. The best strategy for P2 in this simple game is to choose the index that yields the second best payoff as P1 can block the first best.
P1 only cares to disrupt this best move. The three possible moves for P1 are to 1) pick the argmax of the simple game, 2) pick the other index that gives the first best payoff, 3) pick the other index that gives the second best payoff.
These are the only moves that disrupt the strategy of P2 in the simple game. Python submission
Can someone explain why this code is working for 2156A - Pizza Time
It performs around 10^11 operations in the worst case!!
If I'm not wrong , The
O2andO3optimizations in GCC compiler optimize this to $$$\mathcal{O}(1)$$$Compilers will optimize certain statements, for example...
I misread problem E at first, thinking the beauty was defined as min($$$b_j$$$ — $$$b_i$$$) instead of max($$$b_j$$$ — $$$b_i$$$). I couldn't make any progress on this changed version, wondering if anyone else has some ideas.
F2 is so fun but F1 is too easy.
why did problem B accept solutions where you go around the string infinitely until you make a=0 but after contest it does not accept that solution anymore?
orz
"pizza time"
To make sure Hao eats as much as possible, he needs to keep the leftover group (m_3) as small as he can. Whatever is left over becomes the pizza for the next day. By picking the two smallest groups, (m_1) and (m_2), to be as big as possible, we limit (m_3) to at most 1 or 2 slices. This means the total amount of pizza decreases by about 2 slices each day. The game ends when there are only 1 or 2 slices left since no more splitting can happen. Therefore, the number of full cycles where Hao gets to eat is the number of times we can subtract 2 before getting to 1, which is (\lfloor (n-1)/2 \rfloor). Thus, the maximum slices Hao can eat is ((n — 1) / 2).
For problem D, Hint 3 (and thus the solution) is incorrect (counterexample: n = 34, the sum in Hint 3 gets 69 >= 68).
Regarding $$$F1$$$, in solution-1, why is it guaranteed that in next positions we will still be able to change them to their optimal values? Like when we keep updating some position until it reaches its optimal value, during this process, multiple values in the suffix will increment, so why something like this for example is guaranteed to not have a negative impact when we go to the next positions?
Also in the other solution of continuously picking the smallest number, I understand that in an optimal solution if we do 2 consecutive operations on disjoint element, where the first operation is on the larger value, we can swap them to make the small-value operation come first. But for the part of repeatedly reducing some value as long as we can, I understand this does not impact the prefix, but why is it guaranteed to not affect the suffix negatively in reaching its optimal?
i dont know about others but the editorial by very least on C is really bad.
Please note that the editorial is dependent on reading hints.