⭐ Hope you enjoyed the problems! ⭐
Idea: Hamed_Ghaffari
Preparation: Hamed_Ghaffari
If Hamed waits $$$d$$$ days before withdrawing, the amount of money in his card increases by exactly $$$2^d$$$.
For fixed $$$a+b$$$, is $$$2^a+2^b$$$ larger when $$$a,b$$$ are close together, or when one is as large as possible?
If Hamed waits $$$d$$$ days before withdrawing, the amount of money in his card increases by exactly $$$2^d$$$.
Therefore the problem becomes: Split $$$n$$$ into exactly $$$k$$$ positive integers $$$a_1,\dots,a_k$$$, and maximize
For fixed $$$a+b$$$, $$$2^a+2^b$$$ is larger when one of them is as large as possible.
Suppose two segment lengths are $$$a\le b$$$, with $$$a \gt 1$$$. Move one day from the smaller segment to the larger one:
Compare the contributions:
So this change always increases the answer.
Hence, in an optimal solution, we cannot have two segments with length greater than $$$1$$$. We keep transferring days from smaller segments to the largest one until all but one segment have length $$$1$$$.
Thus the optimal lengths are
So the maximum amount is $$$2^{n-k+1}+2(k-1)$$$
#include <bits/stdc++.h>
using namespace std;
int main() {
cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0);
int tc;
cin >> tc;
while(tc--) {
int n, k;
cin >> n >> k;
cout << (1<<(n-k+1)) + 2*(k-1) << '\n';
}
return 0;
}
2269B - KiaKio and Squared Numbers
Idea: sweetweasel
Preparation: sweetweasel
What is the maximum possible value of (f(x)), where (f(x)) is the sum of the squares of the decimal digits of (x)?
Notice that after just one operation, every value becomes at most (729).
Since all values eventually become small, what happens if we repeatedly apply the operation?
Try to detect the cycles of the function (f). Can two numbers that enter the same cycle still behave differently?
Fact
The only cycles of the function $$$f(x)$$$ are
and
Every positive integer eventually reaches exactly one of these two cycles.
Solution
For each initial value $$$a_i$$$, we simulate the process until it reaches one of the two cycles.
If it reaches $$$1$$$, we assign it the signature $$$8$$$.
Otherwise, suppose it takes $$$s$$$ operations to reach the element at position $$$k$$$ of the 8-cycle, where the positions are numbered from $$$0$$$ to $$$7$$$.
Its position after $$$t$$$ operations is
Therefore, two numbers entering the 8-cycle will eventually have identical values at every step if and only if:
We use this value as the signature of each number.
Thus, two initial values are in tune if and only if their signatures are equal.
Let $$$cnt[x]$$$ be the number of elements with signature $$$x$$$. The answer is
Since every number reaches a cycle after a constant number of operations, we can calculate all signatures and count the pairs in $$$\mathcal{O}(n)$$$ time per test case.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define F first
#define S second
#define endl '\n'
#define Mp make_pair
#define pb push_back
#define pf push_front
#define size(x) (ll)x.size()
#define all(x) x.begin(), x.end()
#define fuck(x) cout<<"("<<#x<<" : "<<x<<")\n"
const int N = 2e5 + 100, lg = 18;
const ll Mod = 1e9 + 7;
const ll inf = 1e18 + 10;
// The unique non-trivial cycle of the "sum of squared decimal digits" map.
// 4 -> 16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4 ...
const ll CYC[8] = {4, 16, 37, 58, 89, 145, 42, 20};
int t, n;
ll cnt[9];
// Signature of a lighthouse:
// 8 -> "calm": the value reaches 1 and stays there forever.
// 0..7 -> "restless": the phase of the lighthouse on the 8-cycle.
// Two lighthouses are in tune iff their signatures are equal.
int sig(ll x) {
ll s = 0;
while (true) {
if (x == 1) return 8;
for (int k = 0; k < 8; k++)
if (x == CYC[k]) return (int)(((k - s) % 8 + 8) % 8);
ll y = 0;
while (x > 0) { ll r = x % 10; y += r * r; x /= 10; }
x = y;
s++;
}
}
void work() {
cin >> n;
for (int i = 0; i <= 8; i++) cnt[i] = 0;
for (int i = 1; i <= n; i++) {
ll a; cin >> a;
cnt[sig(a)] ++;
}
ll ans = 0;
for (int i = 0; i <= 8; i++) ans += cnt[i] * (cnt[i] - 1) / 2;
cout << ans << endl;
}
void reset_work() {
return;
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
cin >> t;
while (t --) {
work();
reset_work();
}
return 0;
}
2269C - K Is Important / 2268A - K Is Important
Idea: eren__
Preparation: eren__
Consider the special case where $$$2k = n$$$. Which elements are competing against each other to be deleted?
You can prove that for a specific index $$$i$$$, we are forced to delete exactly one element from the symmetric pair $$$(a_i, a_{n-i+1})$$$. Therefore, to maximize the sum, we should greedily take $$$\max(a_i, a_{n-i+1})$$$.
We can analyze the problem by splitting it into two cases based on the relationship between $$$2k$$$ and $$$n$$$:
Case 1: $$$2k \le n$$$ The elements in the middle, where $$$k \le i \le n - k + 1$$$, are inevitably going to be deleted. No matter what sequence of operations we choose, these elements will eventually land on the $$$k$$$-th position from either the left or the right side. Thus, we unconditionally add all of them to our total sum.
After removing the middle section, we are left with a prefix of length $$$k-1$$$ and a suffix of length $$$k-1$$$.
Proof of the pairing relation: Notice that when the remaining array shrinks to exactly length $$$k + i - 1$$$ (for $$$1 \le i \le k - 1$$$), the $$$k$$$-th element from the left and the $$$k$$$-th element from the right correspond exactly to the original elements $$$a_{n-i+1}$$$ and $$$a_i$$$ (or what remains of their relative positions). At this specific length, the operation forces us to delete exactly one of them.
Therefore, for each $$$1 \le i \le k - 1$$$, we must choose exactly one element from the pair $$$(a_i, a_{n-i+1})$$$. To maximize our score, we greedily add $$$\max(a_i, a_{n-i+1})$$$ to our answer.
Case 2: $$$2k \gt n$$$ This case is very similar, but the roles are inverted. The elements in the middle, where $$$n - k + 2 \le i \le k - 1$$$, are completely fixed and safe. The total length of the array will drop below $$$k$$$ before these elements can ever reach the $$$k$$$-th position from either boundary. Thus, they can never be deleted.
For the remaining valid elements on the two boundaries, the exact same symmetric relationship holds. We form pairs from the two ends: $$$(a_i, a_{n-i+1})$$$ for $$$1 \le i \le n - k + 1$$$. Just like in the first case, we can delete exactly one element from each pair, so we greedily add $$$\max(a_i, a_{n-i+1})$$$ to our sum.
Using two pointers (l and r) allows us to implement both cases cleanly in $$$\mathcal{O}(n)$$$.
#include <bits/stdc++.h>
#define pb push_back
#define F first
#define S second
#define all(a) a.begin(),a.end()
#define sz(a) (int)a.size()
#define pii pair<ll,ll>
#define ll long long
#define ld long double
#define rep(i , a , b) for(int i = (a) ; i <= (b) ; i++)
#define per(i , a , b) for(int i = (a) ; i >= (b) ; i--)
using namespace std ;
const int maxn = 5e5 + 10 ;
int a[maxn] ;
signed main(){
ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);
int t ;cin >> t ;
while(t--){
int n , k ; cin >> n >> k;
for(int i = 1 ;i <= n ; i++){
cin >> a[i] ;
}
ll sum = 0 ;
vector <int> vec;
for(int i = 1 ; i <= n ; i++){
if(i >= k && i <= n-k+1){
sum += a[i] ;
continue ;
}
vec.pb(a[i]) ;
}
int t2 = max(0 , sz(vec)- (k-1)) ;
int l = 0 , r= sz(vec)-1 ;
while(t2--){
sum += max(vec[l] , vec[r]) ;
l++;
r--;
}
cout << sum << "\n" ;
}
}
2269D - What a SauSaGe! It's All Meat / 2268B - What a SauSaGe! It's All Meat
Idea: _R00T
Preparation: _R00T
Write all possible values of $$$3k$$$ in binary. What property of each $$$a_i$$$ is preserved after every operation?
Show that instead of two adjacent elements, we can apply the same XOR mask to any pair $$$a_i,a_j$$$.
By combining several operations, we can XOR two chosen elements by any four-bit number with an even number of set bits.
An element with an odd number of set bits can never become All-Meat. To prove that every other element can become All-Meat, consider these two cases separately: - There is an element with odd popcount. - All elements have even popcount.
The possible XOR masks in one operation are:
Their binary representations are:
All these masks have an even number of set bits. XORing a number with such a mask flips an even number of its bits, so the parity of its popcount does not change.
The All-Meat values smaller than $$$16$$$ are:
or in binary:
They all have even popcount. Therefore, an element with odd popcount can never become All-Meat. This gives us the following upper bound:
Now we prove that this upper bound can always be achieved.
First, we can apply the same mask to any two elements, not necessarily adjacent ones. Suppose we want to apply a mask to $$$a_i$$$ and $$$a_j$$$, where $$$i \lt j$$$. Apply it to every adjacent pair:
Every element strictly between $$$i$$$ and $$$j$$$ is XORed twice, so it remains unchanged. Only $$$a_i$$$ and $$$a_j$$$ are XORed once.
We can also combine multiple operations on the same pair. The set of all four-bit values with even popcount is:
All of them are already valid masks except $$$5$$$ and $$$10$$$, and:
Thus, we can XOR any two chosen elements by any mask with even popcount.
Equivalently, if we write the array as an $$$n\times4$$$ grid of bits, we may choose any two rows and any two columns and flip the four corner bits.
We now consider two cases.
Case 1: There is an element with odd popcount.
Choose one such element as a buffer.
For every element $$$a_i$$$ with even popcount, XOR both $$$a_i$$$ and the buffer by $$$a_i$$$. This is possible because $$$a_i$$$ itself has even popcount.
After this operation:
so $$$a_i$$$ becomes All-Meat. The buffer still has odd popcount because we only XOR it with even-popcount masks.
Therefore, every element with even popcount becomes All-Meat, while the elements with odd popcount cannot contribute to the answer anyway.
Case 2: All elements have even popcount.
Use $$$a_1$$$ as a buffer. For every $$$2\leq i\leq n$$$, XOR $$$a_1$$$ and $$$a_i$$$ by $$$a_i$$$. This makes every $$$a_i$$$ for $$$i\geq2$$$ equal to zero.
After these operations, the array has the form:
where:
Since all original elements have even popcount, $$$x$$$ also has even popcount. If $$$x$$$ is one of:
then every element is already All-Meat.
The only remaining possibilities are $$$x=5$$$ and $$$x=10$$$. In both cases, apply XOR with $$$3$$$ to the first two elements:
Again, every element becomes All-Meat.
Therefore, the upper bound is always achievable, and the answer is exactly:
For each update, we only need to remove the contribution of the old value and add the contribution of the new value.
The initial array is processed in $$$\mathcal{O}(n)$$$, and every update is processed in $$$\mathcal{O}(1)$$$. Therefore, the total time complexity is $$$\mathcal{O}(n+q)$$$.
#include <bits/stdc++.h>
using namespace std;
inline bool good(int x) {
return __builtin_popcount(x) % 2 == 0;
}
int32_t main() {
cin.tie(0);
cout.tie(0);
ios_base::sync_with_stdio(0);
int tc;
cin >> tc;
while (tc--) {
int n, q;
cin >> n >> q;
vector<int> a(n);
int answer = 0;
for (int &x : a) {
cin >> x;
answer += good(x);
}
cout << answer;
while (q--) {
int p, x;
cin >> p >> x;
--p;
answer -= good(a[p]);
a[p] = x;
answer += good(a[p]);
cout << ' ' << answer;
}
cout << '\n';
}
return 0;
}
2269E - KiaKio and Energy Intervals / 2268C - KiaKio and Energy Intervals
Idea: sweetweasel
Preparation: sweetweasel
Let:
If $$$m=\max(a_l,a_{l+1},\ldots,a_r)$$$, show that the value of the interval is:
Build the maximum Cartesian tree of the original array.
What is the relation between $$$\operatorname{LCA}(l,r)$$$ and the maximum element of $$$a_l,a_{l+1},\ldots,a_r$$$?
Construct the answer greedily from the highest bit to the lowest bit.
For a candidate mask $$$M$$$, we only need to determine whether there exists an interval whose value contains every bit of $$$M$$$.
For a fixed candidate $$$M$$$, define:
and let $$$s_i$$$ be the prefix XOR of $$$b$$$.
An interval represented by a Cartesian-tree vertex $$$v$$$ is valid for $$$M$$$ if:
and:
Suppose the subtree of $$$v$$$ represents the segment $$$[L,R]$$$.
For an interval whose Cartesian-tree LCA is $$$v$$$, its two prefix endpoints satisfy:
Be careful with the pair $$$(v-1,v)$$$: it represents the forbidden one-element interval $$$[v,v]$$$.
Process the smaller child first, remove its prefix XORs from the frequency array, and then process the larger child.
Keep the larger side in the frequency array, iterate over the smaller side, and search for the required complementary prefix XOR.
Define the prefix XORs of the original array as:
Suppose we choose an interval $$$[l,r]$$$, and let:
Bitwise AND distributes over XOR, so:
Therefore, the answer depends only on the XOR of two prefix endpoints and the maximum of the interval.
Cartesian tree
Build the maximum Cartesian tree of the original array $$$a$$$. Ties may be handled in any consistent way.
This tree has two useful properties:
- The subtree of every vertex $$$v$$$ corresponds to a continuous segment $$$[L_v,R_v]$$$.
- For every interval $$$[l,r]$$$:
Thus, if $$$v=\operatorname{LCA}(l,r)$$$, the value of the interval is:
Constructing the answer bit by bit
Suppose some higher bits of the answer have already been fixed, and we want to test a candidate mask $$$M$$$.
The candidate is feasible if there exists an interval whose value contains every bit of $$$M$$$.
For this check, define:
and its prefix XORs:
Equivalently:
For an interval whose Cartesian-tree LCA is $$$v$$$, all bits of $$$M$$$ occur in its value if and only if:
and:
The second condition can be rewritten as:
Therefore, after fixing one endpoint, we only need a frequency array to determine whether the required other endpoint exists.
Notice that the Cartesian tree is always built from the original values. Only the prefix XORs are masked during a feasibility check.
Processing one Cartesian-tree vertex
Suppose the subtree of $$$v$$$ corresponds to $$$[L,R]$$$.
Every interval whose LCA is exactly $$$v$$$ can be represented by two prefix endpoints:
We need to find a pair satisfying:
There is one important exception. The pair:
represents the interval $$$[v,v]$$$, which is forbidden because the statement requires $$$l \lt r$$$.
Moreover, whenever $$$a_v & M=M$$$, this pair automatically satisfies:
So failing to exclude this exact pair would produce a false positive at every suitable vertex.
Small-to-large traversal
For every processed subtree $$$[L,R]$$$, we maintain the following invariant:
The frequency array contains $$$s_L,s_{L+1},\ldots,s_R$$$.
At a vertex $$$v$$$:
- Recursively check both child subtrees.
- Keep the prefix XORs of the larger child in the frequency array.
- Iterate over the endpoints belonging to the smaller side.
- For every value $$$s_x$$$, check whether $$$s_x\oplus M$$$ exists on the other side.
- Merge the smaller side into the frequency array.
The boundary prefix $$$s_{L-1}$$$ is inserted temporarily when needed.
The pair $$$(v-1,v)$$$ is excluded by checking one boundary endpoint before inserting the other one. Since the frequency array stores counts rather than only presence, equal prefix XOR values at different indices are still handled correctly.
Whenever an index is scanned as part of the smaller side, the size of the subtree containing it at least doubles before it can be scanned again. Hence, every index is scanned at most $$$\mathcal{O}(\log n)$$$ times.
One feasibility check takes:
There are $$$18$$$ bits, so the total time complexity is:
The memory complexity is:
The implementation below uses an explicit stack because a Cartesian tree can have depth $$$n$$$ for a sorted array.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define F first
#define S second
#define endl '\n'
#define Mp make_pair
#define pb push_back
#define pf push_front
#define size(x) (ll)x.size()
#define all(x) x.begin(), x.end()
const int N = 2e5 + 100, lg = 18;
const ll Mod = 1e9 + 7;
const ll inf = 1e18 + 10;
ll MOD(ll a, ll mod=Mod) {
a%=mod; (a<0)&&(a+=mod); return a;
}
ll poww(ll a, ll b, ll mod=Mod) {
ll res = 1;
while(b > 0) {
if(b%2 == 1) res = MOD(res * a, mod);
b /= 2;
a = MOD(a * a, mod);
}
return res;
}
int t, n, a[N], par[lg][N], pref[N], cnt[N * 2], answ = 0, maxi = 0;
int getmx(int l, int r) {
int res = l;
for(int i=lg-1; i>=0; i--) {
if(l + (1<<i) - 1 <= r) {
res = (a[par[i][l]] > a[res] ? par[i][l] : res);
l += (1<<i);
}
}
return res;
}
void divide(int l, int r) {
if(l > r) return;
if(l == r) {
cnt[pref[l]] ++;
return;
}
if(l == r-1) {
cnt[pref[l]] ++;
cnt[pref[r]] ++;
if((max(a[l], a[r]) & answ) == answ) {
maxi = max(maxi, pref[l-1] ^ pref[r]);
}
return;
}
int mid = getmx(l, r);
if(r-mid > mid-l) {
divide(l, mid-1);
for(int i=l; i<mid; i++) cnt[pref[i]] --;
divide(mid+1, r);
for(int i=mid-1; i>=l-1; i--) {
if(cnt[(answ ^ pref[i])] > 0 && (a[mid]&answ) == answ) maxi = answ;
if (i == mid-1) cnt[pref[mid]] ++;
}
for(int i=mid-1; i>=l; i--) cnt[pref[i]] ++;
} else {
divide(mid+1, r);
for(int i=mid+1; i<=r; i++) cnt[pref[i]] --;
divide(l, mid-1);
cnt[pref[mid-1]] --;
cnt[pref[l-1]] ++;
for(int i=mid; i<=r; i++) {
if(cnt[(answ ^ pref[i])] > 0 && (a[mid]&answ) == answ) maxi = answ;
if(i == mid) cnt[pref[mid-1]] ++;
}
cnt[pref[l-1]] --;
for(int i=mid; i<=r; i++) cnt[pref[i]] ++;
}
}
bool check() {
maxi = 0;
for(int j=1; j<=n; j++) {
pref[j] = pref[j-1] ^ (a[j] & answ);
}
divide(1, n);
for(int i=1; i<=n; i++) {
cnt[pref[i]] = 0;
}
if(maxi == answ) return 1;
return 0;
}
void work() {
cin>>n;
int mxtmp = 0, anstmp = 0;
for(int i=1; i<=n; i++) {
cin>>a[i];
mxtmp = max(mxtmp, a[i]);
par[0][i] = i;
}
for(int i=1; i<=n; i++) anstmp ^= (a[i] & mxtmp);
for(int i=n; i>=1; i--) {
for(int j=1; j<lg; j++) {
int x = par[j-1][i], y = par[j-1][min(n, i + (1<<(j-1)))];
if(a[x] > a[y]) par[j][i] = x;
else par[j][i] = y;
}
}
for(int i=lg-1; i>=0; i--) {
answ += (1 << i);
if(check() == 0) {
answ -= (1 << i);
}
}
cout<<max(answ, anstmp)<<endl;
}
void reset_work() {
answ = 0;
for(int i=1; i<=n; i++) a[i] = 0, pref[i] = 0;
return;
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
// freopen("inp.txt", "r", stdin);
// freopen("out-m.txt", "w", stdout);
cin>>t;
// t = 1;
while(t --) {
work();
reset_work();
}
return 0;
}
2269F - AghaBalaSar and Hamed / 2268D - AghaBalaSar and Hamed
Idea: Hamed_Ghaffari
Preparation: Hamed_Ghaffari
AghaBalaSar (آقابالاسر) is a term commonly used in the Iranian CP community for the nearest greater/smaller element on either side.
I also used it in a previous contest as well :D 2127F - Hamed and AghaBalaSar
For a fixed $$$i$$$, try to describe the shape of a shortest path. In particular, how many times do we really need to move left?
For a fixed $$$i$$$, what can we say about the positions $$$j$$$ whose $$$f(i, j)$$$ are $$$1$$$, $$$2$$$, or greater than $$$2$$$?
The important observation is that a shortest path has the form
So after at most one initial left move, all right moves are forced.
Let $$$R_i=\text{the first }j \gt i\text{ such that }p_j \gt p_i$$$ or $$$n+1$$$ if it does not exist.
We split the permutation into blocks ending at positions $$$r$$$ with $$$R_r=n+1$$$, because we cannot move from one block to any of the blocks to its right.
Let $$$dp_i$$$ be the sum of distances from $$$i$$$ to all positions in the current block.
Let $$$x$$$ be the rightmost position reachable from $$$i$$$ in at most two moves.
There are two cases.
Case 1: ($$$x=R[i]$$$)
Then there is no way to reach anything beyond $$$R_i$$$ in two moves.
Therefore, for every $$$j \gt R_i$$$, every shortest path starts with $$$i\to R_i$$$, hence $$$f(i,j)=1+f(R_i,j)$$$.
Now compare the contributions of $$$i$$$ and $$$R_i$$$.
- For $$$j \lt i$$$, both distances are $$$1$$$.
- For $$$j=i$$$, we gain $$$-1$$$.
- For $$$j \gt i$$$, the distance from (i) is exactly one larger than the corresponding distance from $$$R_i$$$.
The total difference simplifies to $$$dp_i-dp_{R_i}=r-i-1$$$. Thus
Where $$$r$$$ is the end of the current block.
Case 2: ($$$x \gt R_i$$$)
Now $$$x$$$ is reachable in two moves, and $$$x$$$ is the furthest position with this property.
For every $$$j \gt x$$$, $$$f(i,j)=2+f(x,j)$$$.
Why? We can reach $$$x$$$ in two moves and then follow an optimal path from $$$x$$$. Also, by definition of $$$x$$$, no position farther right can be reached from $$$i$$$ in two moves, so we cannot do better.
Thus, for everything after $$$x$$$, we can simply use $$$dp_x$$$.
It remains to handle the positions between $$$i$$$ and $$$x$$$.
Since $$$x$$$ is reachable in at most two moves, every position $$$j\in(i,x]$$$ has distance either $$$2$$$ or $$$3$$$ from $$$i$$$.
Let $$$c_2$$$ be the number of $$$j \in (i,x]$$$ such that $$$f(i,j)=2$$$.
There are $$$x-i-1$$$ positions strictly between $$$i$$$ and $$$x$$$. Among them, $$$c_2-1$$$ have distance $$$2$$$, because $$$x$$$ itself is also counted by $$$c_2$$$. Therefore the remaining $$$x-i-c_2$$$ positions have distance $$$3$$$. Comparing their contributions with $$$dp_x$$$, we get
So the only remaining problem is computing $$$x$$$ and $$$c_2$$$ efficiently.
Finding the positions reachable in two moves
A position $$$j \gt i$$$ can be reached in two moves in exactly these ways:
- $$$i \lt j \lt R_i$$$, by $$$i\to R_i\to j$$$;
- $$$j=R_{R_i}$$$;
- There is some $$$k\le i$$$ such that $$$R_k=j$$$, because we can do $$$i\to k\to j$$$.
Let $$$L_j$$$ be the minimum $$$k$$$ such that $$$R_k = j$$$, then third case is simply $$$L_j\le i$$$.
We process $$$i$$$ from right to left and maintain all positions $$$j$$$ satisfying $$$L_j\le i$$$. The rightmost marked position is exactly $$$x$$$.
Computing $$$c_2$$$
Among the distance-$$$2$$$ positions we have:
- $$$R_i-i-1$$$ positions between $$$i$$$ and $$$R_i$$$;
- $$$R_{R_i}$$$, if it exists;
- all currently marked positions except $$$R_i$$$.
There is one possible double count: $$$R_{R_i}$$$ may itself already be marked.
So we can compute $$$c_2$$$ by processing $$$i$$$ from right to left and maintaining all marked positions.
Complexity: $$$\mathcal{O}(n)$$$
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MXN = 1e6+5;
int n, p[MXN], R[MXN], L[MXN];
ll dp[MXN];
vector<int> vec[MXN];
bool mark[MXN];
void solve(int l, int r) {
dp[r] = r-l;
int lst=r, cnt=0;
if(L[r]!=n+1) {
vec[L[r]].push_back(r);
mark[r] = 1;
cnt++;
}
for(int i=r-1; i>=l; i--) {
while(!mark[lst]) lst--;
if(lst==R[i]) {
dp[i] = dp[R[i]] + r-l+1 - 2 - (i-l);
}
else {
int c1 = i-l + 1;
int c2 = R[i]-i-1 + (R[R[i]]!=n+1) + cnt - 1 - (R[R[i]]!=n+1 && L[R[R[i]]]<=i);
dp[i] = dp[lst] + 2*(r-l+1) - 3 - 2*c1 - c2 + 1;
}
for(int j : vec[i])
mark[j] = 0,
cnt--;
if(L[i]!=n+1) {
vec[L[i]].push_back(i);
mark[i] = 1;
cnt++;
}
}
for(int i=l; i<=r; i++)
dp[i] += l-1;
}
void Main() {
cin >> n;
for(int i=1; i<=n; i++) {
cin >> p[i];
vec[i].clear();
mark[i] = 0;
}
fill(L+1, L+n+1, n+1);
for(int i=n; i>=1; i--) {
for(R[i]=i+1; R[i]<=n && p[R[i]]<p[i]; R[i]=R[R[i]]);
L[R[i]] = i;
}
int l=1;
for(int r=1; r<=n; r++)
if(R[r]==n+1) {
solve(l, r);
l = r+1;
}
ll ans = 0;
for(int i=1; i<=n; i++)
ans += dp[i];
cout << ans << '\n';
}
int32_t main() {
cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0);
int T;
cin >> T;
while(T--) Main();
return 0;
}
2268E - Kia Kio and Tree of Life
Idea: sweetweasel
Preparation: Hamed_Ghaffari and _R00T
The number of valid trees that can be constructed from a segment of length $$$m$$$ is the $$$m$$$-th Catalan number.
The vertices inside every subtree form a continuous subarray. Fix a subarray of length $$$l$$$. In how many trees does it appear as the subtree below some edge?
Exactly $$$C_lC_{n-l}$$$, where $$$C_i$$$ is the $$$i$$$-th Catalan number.
Consider every bit independently. If the XOR of the entire array has this bit set, exactly one of the two components created by cutting any edge has this bit set.
Suppose the bit is not set in the XOR of the entire array. We need, for every length $$$l$$$, the number of subarrays of length $$$l$$$ whose XOR has this bit set.
Let $$$p_i=a_1\oplus a_2\oplus\cdots\oplus a_i$$$. Encode the corresponding bit of each $$$p_i$$$ as either $$$1$$$ or $$$-1$$$. The number of pairs with different signs can be found from their autocorrelation.
We only need a weighted sum of the autocorrelation values. Using Parseval's identity, this weighted sum can be calculated without performing an inverse NTT for every bit.
Let $$$C_m$$$ be the $$$m$$$-th Catalan number:
The recursive construction in the statement generates exactly the binary trees whose inorder traversal is:
Therefore, there are $$$C_n$$$ valid trees.
Consider an edge between a parent and one of its children. The component containing the child after removing this edge is exactly the child's subtree. Since the inorder traversal is fixed, the vertices of this subtree form a continuous subarray.
Now fix a proper subarray $$$[L,R]$$$ of length $$$l$$$.
There are $$$C_l$$$ possible trees inside this subarray. After deleting this subtree, the remaining $$$n-l$$$ vertices can form any valid tree, giving $$$C_{n-l}$$$ possibilities.
The location of $$$[L,R]$$$ determines one gap in the inorder traversal of the remaining tree. This gap corresponds to a unique empty child position, so the chosen subtree can be attached there in exactly one way.
Therefore, a fixed subarray of length $$$l$$$ appears as the child subtree of an edge in exactly:
valid trees.
Let:
For a subarray $$$I$$$, let its XOR be $$$X_I$$$. Cutting the edge above this subtree produces two components with XOR values:
Thus, the whole answer can be written as:
We calculate this sum bit by bit.
Fix a bit $$$b$$$.
Case 1: Bit $$$b$$$ of $$$S$$$ is set.
At this bit, $$$X_I$$$ and $$$S\oplus X_I$$$ are different. Therefore, exactly one of the two components has this bit set for every tree and every edge.
There are $$$C_n$$$ trees, and every tree has $$$n-1$$$ edges. Hence, before multiplying by $$$2^b$$$, the contribution is:
Case 2: Bit $$$b$$$ of $$$S$$$ is not set.
In this case, the two component XORs have the same value at bit $$$b$$$.
- If bit $$$b$$$ of $$$X_I$$$ is zero, the edge contributes zero.
- If bit $$$b$$$ of $$$X_I$$$ is one, both components contribute this bit, so the edge contributes twice.
For every length $$$l$$$, let $$$D_l$$$ be the number of subarrays of length $$$l$$$ whose XOR has bit $$$b$$$ set. The contribution of this bit is:
It remains to calculate every $$$D_l$$$.
Define the prefix XORs:
The XOR of a subarray of length $$$l$$$ starting after position $$$i$$$ is:
Define:
The required subarray has bit $$$b$$$ set exactly when $$$s_i$$$ and $$$s_{i+l}$$$ are different.
Consider:
Equal pairs contribute $$$1$$$, while different pairs contribute $$$-1$$$. Since there are $$$n+1-l$$$ pairs in total:
Therefore:
The values $$$R_l$$$ form the autocorrelation of the sequence $$$s$$$. After padding the sequence with enough zeros, let $$$F_k$$$ be its NTT. The NTT representation of the autocorrelation is:
With a transform of size $$$N$$$, the index $$$-k$$$ is represented by $$$(N-k)\bmod N$$$.
A direct implementation could perform an inverse NTT and obtain every $$$R_l$$$. However, we only need their weighted sum.
Let:
for $$$1\leq l \lt n$$$, and let $$$W_k$$$ be the NTT of $$$w$$$. Using Parseval's identity:
Also:
The first sum is independent of the bit and can be precomputed. The second sum is calculated using one forward NTT and Parseval's identity.
Therefore, we need one NTT for the weights and at most one NTT for each of the $$$18$$$ bits.
The total time complexity is:
and the memory complexity is $$$\mathcal{O}(n)$$$.
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int mod = 998244353;
const int G = 3;
const int B = 18;
const int N = 200000;
int qpow(int a, int b) {
int r = 1;
while (b) {
if (b & 1) r = (i64)r * a % mod;
a = (i64)a * a % mod;
b >>= 1;
}
return r;
}
struct NTT {
int n;
vector<int> rev, roots;
NTT(int n) : n(n), rev(n), roots(n) {
for (int i = 1; i < n; i++) {
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (n >> 1) : 0);
}
for (int len = 1; len < n; len <<= 1) {
int z = qpow(G, (mod - 1) / (len << 1));
roots[len] = 1;
for (int i = 1; i < len; i++) {
roots[len + i] = (i64)roots[len + i - 1] * z % mod;
}
}
}
void transform(vector<int>& a) const {
for (int i = 0; i < n; i++) {
if (i < rev[i]) swap(a[i], a[rev[i]]);
}
for (int len = 1; len < n; len <<= 1) {
for (int i = 0; i < n; i += len << 1) {
for (int j = 0; j < len; j++) {
int x = a[i + j];
int y = (i64)a[i + j + len] * roots[len + j] % mod;
a[i + j] = x + y;
if (a[i + j] >= mod) a[i + j] -= mod;
a[i + j + len] = x - y;
if (a[i + j + len] < 0) a[i + j + len] += mod;
}
}
}
}
};
vector<int> fac(2 * N + 1);
vector<int> ifac(2 * N + 1);
vector<int> catalan(N + 1);
void init() {
fac[0] = 1;
for (int i = 1; i <= 2 * N; i++) {
fac[i] = (i64)fac[i - 1] * i % mod;
}
ifac[2 * N] = qpow(fac[2 * N], mod - 2);
for (int i = 2 * N; i >= 1; i--) {
ifac[i - 1] = (i64)ifac[i] * i % mod;
}
for (int i = 0; i <= N; i++) {
catalan[i] = (i64)fac[2 * i] * ifac[i] % mod
* ifac[i + 1] % mod;
}
}
void solve() {
int n;
cin >> n;
vector<int> a(n), pref(n + 1);
for (int& x : a) cin >> x;
if (n == 1) {
cout << 0 << '\n';
return;
}
for (int i = 1; i <= n; i++) {
pref[i] = pref[i - 1] ^ a[i - 1];
}
vector<int> weight(n);
int W = 0;
for (int d = 1; d < n; d++) {
weight[d] = (i64)catalan[d] * catalan[n - d] % mod;
W = (W + (i64)(n - d + 1) * weight[d]) % mod;
}
int len = 1;
while (len < 2 * (n + 1)) len <<= 1;
NTT ntt(len);
vector<int> kernel(len);
for (int d = 1; d < n; d++) {
kernel[d] = weight[d];
kernel[len - d] = weight[d];
}
ntt.transform(kernel);
int answer = (i64)((1 << B) - 1) * W % mod;
int inv_len = qpow(len, mod - 2);
int inv_two = (mod + 1) / 2;
int total_xor = pref[n];
vector<int> seq(len);
for (int b = 0; b < B; b++) {
if ((total_xor >> b) & 1) continue;
fill(seq.begin(), seq.end(), 0);
for (int i = 0; i <= n; i++) {
seq[i] = ((pref[i] >> b) & 1) ? mod - 1 : 1;
}
ntt.transform(seq);
int spectral_sum = 0;
for (int k = 0; k < len; k++) {
int opposite = (len - k) & (len - 1);
int term = (i64)kernel[k] * seq[k] % mod
* seq[opposite] % mod;
spectral_sum += term;
if (spectral_sum >= mod) spectral_sum -= mod;
}
int Q = (i64)spectral_sum * inv_len % mod * inv_two % mod;
answer -= (i64)(1 << b) * Q % mod;
if (answer < 0) answer += mod;
}
cout << answer << '\n';
}
int main() {
cin.tie(0)->sync_with_stdio(0);
init();
int T;
cin >> T;
while (T--) solve();
}
Idea: eren__
Preparation: Hamed_Ghaffari and _R00T
Think of each operation as swapping two elements in each of two columns. Therefore, the parity of the total number of inversions over all columns never changes. So if it is odd, the answer is $$$-1$$$.
Consider the total number of inversions over all columns. One operation can decrease this number by at most $$$2$$$. Since there are $$$2n\binom{2n}{2}$$$ inversions in the worst case, we need at least $$$n\binom{2n}{2}$$$ operations in general. Therefore, our construction can only afford about $$$9n$$$ additional operations.
Process the values in increasing order. For each value $$$x$$$, try to place all occurrences of $$$x$$$ into row $$$x$$$, so that values $$$1,2,\ldots,2n-1$$$ are placed in their correct rows one by one.
Pair the columns: $$$(1,2),(3,4),\ldots$$$. For a fixed $$$x$$$, each pair can contain $$$0,1,$$$ or $$$2$$$ copies of $$$x$$$ in its top row.
Distinguish the two possible one-$$$x$$$ cases: the $$$x$$$ is on top the of left column (we call them $$$L$$$-pairs) or on top of the right column (we call them $$$R$$$-pairs).
Process $$$L$$$-pairs from left to right and $$$R$$$-pairs from right to left. If an $$$L$$$ and $$$R$$$ meet, they can be fixed together.
First, consider the parity of the total number of inversions in all columns.
One operation swaps the two top elements with the two bottom elements. In each affected column, this is equivalent to swapping two elements, so the parity of the inversion count of that column changes. Since two columns are affected, the parity of the total inversion count does not change.
In the final grid every column is sorted, so the total number of inversions is $$$0$$$, which is even.
Therefore, if the initial total number of inversions is odd, the answer is immediately $$$-1$$$.
Now assume it is even.
We process
Our goal at step $$$x$$$ is to put every occurrence of $$$x$$$ into row $$$x$$$.
Pair the columns:
For each pair, look at its two cells in row $$$x$$$.
There are four possibilities:
- Type $$$0$$$: neither cell contains $$$x$$$;
- Type $$$L$$$: only the left cell contains $$$x$$$;
- Type $$$R$$$: only the right cell contains $$$x$$$;
- Type $$$1$$$: both cells contain $$$x$$$.
Our goal is to make every pair Type $$$1$$$. Once this happens, all $$$2n$$$ copies of $$$x$$$ are in row $$$x$$$.
For each $$$x=1,2,\ldots,2n-2$$$, we proceed through the following steps:
1. Consider only the pairs $$$2,3,\ldots,n-1$$$. The first and last pairs will be handled separately.
2. We get rid of all Type $$$1$$$ pairs. For every Type $$$1$$$ pair, perform an operation on that pair. The two $$$x$$$'s are currently on top, so after the operation, they move down and the pair becomes Type $$$0$$$.
3. While there is a Type $$$L$$$ pair, take the leftmost one, say pair $$$i$$$:
3.1. If pair $$$i+1$$$ is Type $$$0$$$ or Type $$$L$$$, move the right $$$x$$$ of pair $$$i$$$ to row $$$x+1$$$ by performing operations on pair $$$i$$$, then perform an operation on pairs $$$i$$$ and $$$i+1$$$. Pair $$$i$$$ becomes Type $$$1$$$.
3.2. If pair $$$i+1$$$ is Type $$$R$$$, leave this Type $$$L$$$ pair for later.
4. While there is a Type $$$R$$$ pair, take the rightmost one, say pair $$$i$$$:
4.1. If pair $$$i-1$$$ is Type $$$0$$$ or Type $$$R$$$, do the symmetric operation: move the appropriate $$$x$$$ to row $$$x+1$$$, then perform an operation so that pair $$$i$$$ becomes Type 1.
4.2. If pair $$$i-1$$$ is Type $$$L$$$, the two pairs form an $$$L$$$-$$$R$$$ configuration. Move the right $$$x$$$ of pair $$$i-1$$$ and the left $$$x$$$ of pair $$$i$$$ to the same row, then perform an operation to move both $$$x$$$'s to the top. Both pairs become Type $$$1$$$.
5. At this point, every middle pair is Type $$$0$$$ or Type $$$1$$$. For each Type $$$0$$$ pair, move its two $$$x$$$'s to the same row and perform an operation to move both to the top. Thus every middle pair becomes Type $$$1$$$.
6. Finally, fix the first and last pairs. They can always be made Type $$$1$$$ using at most $$$2n−x+2$$$ operations (it means we need at most $$$2$$$ additional operations).
For $$$x=2n-1$$$, for each $$$i=1,2,\ldots,2n-1$$$, if $$$a_{2n-1,i}\neq 2n-1$$$, perform an operation on the subgrid whose top-left cell is $$$(2n-1,i)$$$. This requires at most $$$2n-1$$$ operations.
Number of operations
For a fixed $$$x$$$, each pair needs at most $$$2n-x$$$ operations during the main process. There are $$$n$$$ pairs, giving at most $$$n(2n-x)$$$.
The first and last pairs require at most $$$2$$$ additional operations for each $$$x$$$, contributing $$$2\cdot2(2n-2)$$$.
Finally, the $$$x=2n-1$$$ case costs at most $$$n-1$$$ additional operations.
Hence the total is at most
The main sum is
Therefore,
So the required bound is satisfied.
The construction also gives the actual sequence of operations if we implement the described moves.
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
const int MXN = 202;
int n, n2, a[MXN][MXN];
vector<pii> ans;
inline void opr(int i, int j) {
swap(a[i][j], a[i+1][j]);
swap(a[i][j+1], a[i+1][j+1]);
ans.push_back({i, j});
}
inline int wh(int x, int j) {
for(int i=x; i<=n2; i++)
if(a[i][j]==x)
return i;
assert(0);
return -1;
}
inline void R(int x, int j) {
for(int i=wh(x, j+1)-1; i>=x; i--) opr(i, j+1);
}
inline void RL(int x, int j) {
int pos1 = wh(x, j+1), pos2 = wh(x, j+2);
while(pos1>pos2) opr(--pos1, j);
while(pos1<pos2) opr(--pos2, j+2);
while(pos1>x) opr(--pos1, j+1);
}
inline void L(int x, int j) {
for(int i=wh(x, j)-1; i>=x; i--) opr(i, j-1);
}
inline void L1(int x, int j) {
if(a[x+1][j]==x) opr(x+1, j); // extra, we can ignore it for x<=2n-3
opr(x, j-1); // extra, we can ignore it
for(int i=wh(x, j)-1; i>=x+1; i--) opr(i, j);
opr(x, j-1);
}
inline void solve0(int x, int j) {
int pos1=wh(x, j), pos2=wh(x, j+1);
while(pos1>pos2) opr(--pos1, j-1);
while(pos1<pos2) opr(--pos2, j+1);
while(pos1>x) opr(--pos1, j);
}
inline void lft(int x) { // 2 extra
if(a[x][2]==x) {
if(a[x][1]==x) return;
if(a[x+1][1]==x) opr(x+1, 1);
opr(x, 1);
}
else if(a[x][1]==x) {
if(a[x+1][2]==x) opr(x+1, 1);
opr(x, 1);
}
int pos1=wh(x, 1), pos2=wh(x, 2);
if(pos1>pos2) {
while(pos1>pos2) opr(--pos1, 1);
pos2++;
}
while(pos1<pos2) opr(--pos2, 2);
while(pos1>x) opr(--pos1, 1);
}
inline void rgt(int x) { // 2 extra
if(a[x][n2-1]==x) {
if(a[x][n2]==x) return;
if(a[x+1][n2]==x) opr(x+1, n2-1);
opr(x, n2-1);
}
else if(a[x][n2]==x) {
if(a[x+1][n2-1]==x) opr(x+1, n2-1);
opr(x, n2-1);
}
int pos1=wh(x, n2-1), pos2=wh(x, n2);
if(pos1<pos2) {
while(pos1<pos2) opr(--pos2, n2-1);
pos1++;
}
while(pos1>pos2) opr(--pos1, n2-2);
while(pos1>x) opr(--pos1, n2-1);
}
inline void lst() { // 2n-1 extra
for(int j=1; j<=n2-1; j++)
if(a[n2][j]!=n2) opr(n2-1, j);
}
inline void print() {
cout << ans.size() << '\n';
for(auto [x, y] : ans) cout << x << ' ' << y << '\n';
ans.clear();
}
void Main() {
cin >> n;
n2 = n<<1;
for(int i=1; i<=n2; i++)
for(int j=1; j<=n2; j++)
cin >> a[i][j];
int inv = 0;
for(int j=1; j<=n2; j++)
for(int i1=1; i1<=n2; i1++)
for(int i2=i1+1; i2<=n2; i2++)
inv ^= a[i1][j]>a[i2][j];
if(inv) {
cout << "-1\n";
return;
}
if(n==1) {
if(a[1][1]==2) cout << "1\n1 1\n";
else cout << "0\n";
return;
}
for(int x=1; x<=n2-2; x++) {
for(int j=3; j<=n2-3; j+=2)
if(a[x][j]==x && a[x][j+1]==x) opr(x, j);
for(int j=3; j<=n2-3; j+=2)
if(a[x][j]==x && a[x][j+1]!=x) {
if(j==n2-3 || a[x][j+3]!=x) R(x, j);
else RL(x, j);
}
for(int j=n2-3; j>=3; j-=2)
if(a[x][j]!=x && a[x][j+1]==x) {
if(a[x][j-2]==x && a[x][j-1]==x) L1(x, j);
else L(x, j);
}
for(int j=3; j<=n2-3; j+=2)
if(a[x][j]!=x)
solve0(x, j);
lft(x);
rgt(x);
}
lst();
print();
}
int32_t main() {
cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0);
int tc;
cin >> tc;
while(tc--) Main();
return 0;
}
Can you improve the construction and reduce the number of operations below $$$n\binom{2n}{2} + 9n$$$ ?








The gap between D and E is very huge, as 1400 to 2300.
And why $$$O(n^2)$$$ or $$$O(n\log^3n)$$$ can pass E's system test ?????????
In Hint 2 of the editorial for 1F, I believe you meant '2n*comb(2n, 2) inversions in the worst case', rather than 'n*comb(2n, 2)'.
Edited, thanks
E feels soooo hard
In problem D you can also generate the set of possible values and check if the array value belongs to the set or not
PS: I'm sure there are better ways to calculate the set but this seemed to work so why not :)
Yeah, the possible values are all numbers either divisibly 3 or 5. This is because for the set of nonpositive integers less than 16, combining three multiples of three yields a number that is either divisible by 3 or 5. Then you just have to show that any two consecutive numbers in that set can be turned into multiples of three with XOR.
I feel like another solution of D2D/D1B should be mentioned, making the problem not as ad-hoc (and I think that the fact that xor basis of $$$3k$$$ generates exactly all masks with even popcount is a prime example ad-hoc, because it works up to 4 bits).
The solution is as follows: let's do segment tree, and in each node we'll store $$$dp[start][end]$$$ — maximum number of positions on the interval of the node, if we also xor the first element with value $$$start$$$ and the last element $$$end$$$, these operations cover out-of-bounds elements. Then to merge two nodes we actually need to do matrix multiplication, but with operations $$$(\max, +)$$$: $$$dp[s][e] = \max_t dpl[s][t] + dpr[t][e]$$$. The answer is $$$dp[0][0]$$$ in the root node. This solution works in $$$O(16^3 \log n)$$$, which is a lot. But, maybe not every value of xor can be achieved, if we precalc the set of possible values, we get $$$0,3,5,6,9,10,12,15$$$ — $$$8$$$ elements istead of $$$16$$$. Now matrix multiplication takes $$$8^3$$$ operations and the solution passes.
A general Segment Tree + DP solution that doesn't rely on the ai < 16 restriction and works for any ai : note that adjacent pair updates telescope into assigning a net XOR shift vi in W to each element ai, which is valid if and only if the total XOR sum of vi's = 0, where W = span of {3,6,9,12,15} = {0,3,5,6,9,10,12,15} is an 8-element subspace. We can maintain a segment tree where each node stores dp[v] — the maximum number of elements divisible by 3 in its range given a total accumulated XOR sum is v. At a leaf, dp[v] = ((a[i] ^ v) % 3 == 0 ? 1 : 0), and to merge two nodes, we perform XOR group convolution: dp_parent[x ^ y] = max(dp_parent[x ^ y], dp_left[x] + dp_right[y]) for all x, y in W. The answer is dp[0] at the root node, and updates take O(|W|^2 *log N) = O(64 * log N) time.
my submission: https://codeforces.me/contest/2269/submission/392215444
hey man,
see i did the same thing, but i did in terms of incoming and outgoing edge on the given index. But im not able to understand the idea of total xor = 0, seems like some invalid state also gets counted on..
for example, if u see my imple, it would be basically equivalent to taking max(seg.root[x][x]), instead of just [0][0], which doesnt seem to be right, it gives the first and last element an in and out edge..
submission
The 2D merge takes 8^3 = 512 ops, giving 2 * 10^5 queries * 18 depth * 512 = 1.84 * 10^9 operations. While flattening to a 1D state reduces the merge cost to 8^2 = 64 ops (2.3 * 10^8 total ops)
In B, why dont simply repeat the operations until a stable state is reached? (it is accepted)
Yes, I did like this. I used the operation for 49 times for each ai, then just compared those values.
Wait how u guys proved for at most 49 operations they will end up as a same number?
Like if they were in a cycle at different positions in start they eventually don't reach to the same value as the difference in their positions in the cycle remains constant!
Ig I missed the point that some other number that just entered into the cycle which is not in the cycle in the beginning. (for ex: 19 and 7)
Correct me if I am wrong.
49 was obviously a random large safe bound :) Ig u can prove within 11-12 steps the number will reach a stable state, like even if u start with 1e9-1, then f(1e9-1) = 9 * 81 = 729, u can see how drastically the number is converging.
And yes the phase difference of two numbers in a cycle will remain constant and that's why we are not counting those pairs as our answer.
Edit: just see my submission https://codeforces.me/contest/2269/submission/392186819 I have finally grouped the numbers according to their phase and a pair consisting of different phases is not counted
Yep Thanks for ur solution I just stuck at proving things in the contest upsolved it finally! :)
just use 729 ig , after 1st step , we can say ai <= 729 at max coz the maximum 2nd number as per the bound is 729 , when its 1e9 — 1 , after that i think there will be a tighter bound to make all numbers converge but ig 729 is safe as the maximum length of a possible cycle is 729 , although again for the 3rd iteration the bound is for 999 -> 243 and so on . doing for 729 passes well ig as n <= 1000 ,
i did for n = 800 , it got accepted .. 393384992
392257923
Just barely optimized my $$$O(n^\frac{5}{3}\log A)$$$ solution for 2E/1C to pass (idea is binary search + 3D Mo's). It's probably hackable; have fun trying!
Really nice contest, i think for $$$1B$$$ you could also generate the graph for all the $$$16$$$ numbers, and see that all numbers divisible by $$$3$$$ or $$$5$$$ are a maximal connected component, all the other elements cannot reach this component. This is much lazier then the editorial approach but maybe more intuitive during a contest (i did it like this when i upsolved it).
This is the graph as an adjacency list, i hope it makes it clear
Also for the final part, you can see that for each pair $$$(a,b)$$$ in this component there is always a $$$3k$$$ such that they both land in a number divisible by $$$3$$$ ($$$\exists k\;\; 3 \mid a \oplus 3k \land 3 \mid b \oplus 3k$$$). So the upperbound is always achievable as we can always find such $$$3k$$$ for any adjacent pair.
in C, a greedy solution picking max of $$$a[k]$$$ and $$$a[n-k+1]$$$, using an ordered_set or a segment tree works
In problem D1D
Since $$$x$$$ is reachable in at most two moves, every position $$$i \lt j \le x$$$ has distance either 2 or 3 from $$$i$$$ .
What about $$$R_i$$$? Isn't it reachable in 1 move
Yes, this is a mistake, after taking 1 move for Ri and rest 2 or 3, the formula is correct.
The difficulty gap between problems D and E in div2 is too large.After solving D,it’s just garbage time for me.
Problem D idea sharing
I think D is very good problem to show that computer is your best teammate during the contest.
First i don't observe popcount at the begin,i just think if i possible to $$$\oplus$$$ some element from $$$A=\{3,6,9,12,15\}$$$,which number i can get when using element from $$$A$$$ ?This lead to a classic problem,$$$\textbf{xor basis}$$$,given $$$n$$$ numbers,how many distince number you can form,so i just use 5 minutes to quickly run a $$$\textbf{xor basis}$$$ algorithm to see what number i can construct by using element from $$$A$$$,i get a list $$$S=\{0,3,5,6,9,10,12,15\}$$$,i found that the number of element does not appear in $$$S$$$ exactly same as $$$S$$$,and i stuck here,i try to find the pattern to separate element just like parity,the reason is like if i give you $$$[1..n]$$$,you can just separate it into odd number group and even number group,so i believe that,there is some ways like parity to separate them into two group
I just print their binary representation,and i observe something interesting,all element fron $$$S$$$ have a $$$\text{popcount}$$$ even parity and all element not in $$$S$$$ have an $$$\text{popcount}$$$ odd parity,this is important,when i learn FWT ,there is an proof at $$$\text{popcount}$$$,in the rest i will just type popcount as $$$\text{PC}$$$,the proof state that,if $$$x$$$ and $$$y$$$ with same parity of $$$\text{PC}$$$ then $$$x\oplus y$$$ with be the even parity of $$$\text{PC}$$$,otherwise will be odd parity of $$$\text{PC}$$$,now $$$s\in S$$$ is fully even parity of $$$\text{PC}$$$,thus if an element $$$a_i$$$ with odd parity of $$$\text{PC}$$$ will never be a multiple of $$$3$$$,since all multiple of $$$3$$$ have an even parity $$$\text{PC}$$$.
Now the last question is the odd parity $$$\text{PC}$$$ number will separate the array $$$a$$$ into few segment,each segment will all element with even parity $$$\text{PC}$$$,for an segment $$$[l,r]$$$ with length $$$L$$$,is that possible to make all of them divide by $$$3$$$?We define $$$g_i$$$ such that $$$a_i\oplus g_i=3\cdot q$$$,and $$$pfx_i=g_l \oplus g_{l+1} \dots g_i$$$,then just let $$$\forall i \in [l,r) \text{ and } a_i \oplus pfx_i$$$,but the last element $$$a_r \oplus pfx_{r-1}$$$ may not a multiple of $$$3$$$,there is two condition,
So we may conclude that if $$$a_i$$$ with even parity of $$$\text{PC}$$$,then there is possible to make it become multiple of $$$3$$$
My $$$O(18n\log n)$$$ was hacked :(
Was that because of branching to a random bit on trie when some bit is 0 on max(l, r)? or were u reconstructing the trie every time u go up on the cartesian tree with the new mask? idk I couldn't really understand why did people who used Trie get hacked. I was searching for a soulution with Trie and I just realized that branching to different bits when max(l, r)'s bit is 0 leads to two different answers. And is there a working solution with Trie?
U R right, I didn't even notice the issue! thx
You can do a binary search on trie. for example first you are going to aim for getting 1XXX then if you can get the first 1 try 11XX if you can't try achieving 01XX and so on. This is the correct solution if you still want to use Trie unlike the editorial I guess.
Guys, im a newbie to cf, i tried problem B for almost 5+ hrs but still cant able to settle in a decision,
it seems im overlooking something
i checked for self-cycles to break and if the intermediate number found in other process i add to map to prove they form a pair whats wrong, sm1 help
i suggest you to transform each element multiple times (say 100 times), then count equal element pairs
but how can we be so sure that every number $$$x$$$ $$$\in$$$ $$$[1, 10^9]$$$ would be part of a cycle in just $$$100$$$ transformations?
some users got accepted with only $$$49$$$ transformations, so what is the actual upper bound for it, and how do you prove it?
Problem Div2 $$${B}$$$, it's pure guess works, with no valid proof, and a vague solution in the editorial.
There is no proof why every number would eventually be a part of the two cycles mentioned. The only thing convincing is that, the maximum sum of the squares of digits that we can get from a number can be $$$729$$$, so somehow it has to repeat some number after at max $$$729$$$ operations.
But this part is totally missing in the editorial. Maybe the problem isn't bad, but the editorial is definitely bad for the problem Div2 $$${B}$$$.
It's possible to solve the problem without "the fact" (all numbers converge to one of the two cycles). I actually solved the problem in the following way.
First, simulate the process for each number until you find a cycle. For each $$$a_i$$$, record the following $$$(m_i, p_i, c_i)$$$: $$$m_i$$$ is the minimum number in the cycle, $$$p_i$$$ is the (0-based) index where $$$m_i$$$ appears, and $$$c_i$$$ is the length of the cycle.
Then, for every pair of indices $$$(i, j)$$$, compare $$$m_i$$$ and $$$m_j$$$. If $$$m_i \ne m_j$$$, there's no possibility that the two sequences converge. If $$$m_i = m_j$$$, then $$$c_i = c_j$$$ must hold, and then you just need to check $$$p_i \equiv p_j \; (\text{mod} \; c_i)$$$: if this equation holds, the sequences will converge eventually.
notice there is no reason to simulate for each ai, as it might cost up to 240 (but it costs less and n<=1e3 so it still works) but as I have written below you can simulate for a number and not index, you can look at my comment below
Yes I agree, I also find it troubling to understand the solution to Div1 C/ Div 2 E
but you have the following, as you said after one operation all the numbers are from 1 to 729 the graph that has an edge from x to square_digits(x) is a functional graph, just a pretty name for graphs where each node has one place to go, in each connected component in such graph looks like a circle and from each node in the circle there might be a tree, therefore we can say for each number from 1 to 729 run the operation 730 times, now if two numbers were the same they stayed the same therefore you can only check how many pairs are the same, (730 times so every node must get to the circle in the connected componnet)
complexity O(n + 729*730 + 729) = O(n + 730^2)
with no absolute crazy saying that there are only two circles
yeah that's much more intuitive and easy to understand and implement. Also it would easily fit in the time limit.
Hi, zerefx, could you please have a look at my comment?
yeah, your approach makes sense. It's a good way to solve these kinds of problems.
I also think the editorial for D2B is a bit complex. I wonder if anyone found that there were only two cycles in contest mathematically, and what was the motivation?
In addition, I have another solution. Apply the operation (x becomes the sum of square of digits of x) on every $$$a_i$$$ for a lot of times. Now, if two $$$a_i$$$ become the same, we count them, and that's the answer.
We apply the operation on every number for $$$162+3$$$ times, and every number must enter a cycle after this. Then, if $$$x$$$ appeared for $$$y$$$ times in the transformed array, we add $$$\frac{y(y-1)}{2}$$$ to the answer. Time $$$O(165n+162)$$$ or $$$O(n)$$$.
The bound $$$162+3$$$ is obtained by applying the operation on array $$$a_i$$$ multiple $$$3$$$ times. First time, bound becomes $$$729+1$$$. Second time, $$$198+2$$$. Third time is $$$162+3$$$. This can probably be lowered more using some reasoning like any three digit numbers after three operations must go below $$$107$$$ or smth.
submission
Thanks to ItayKarny for the comment mentioned functional graph, it gave me a new idea after the contest!
Since it is a graph where each state has exactly one outgoing edge, we can simulate dfs and use dfn order to preprocess each state's final cycle id, cycle length, and phase in $$$O(num\ of\ states)$$$. Here's my submission:395911228
But when the number of states is small, simply running the operation enough times is undoubtedly a very, very clever choice!
In B, any number being part of these two cycles is not an obvious fact. You need to provide the proof, or atleast the intuition, and not let people brute force the sequences and guess the pattern.
Hi, expertaq, you can look at the comment mentioned functional graph and my comment. Actually, we don't need to prove or find the number of cycles and the cycle lengths by ourselves.
I wasn't able to participate in this contest, so I went to the problemset after to solve a couple problems and clicked problem A. I've never solved a Div 2 C problem in contest, but I accidentally solved it in 5 minutes because I thought it was problem A (it was problem A for Div 1) LOL
This was my solution, seems simpler than the editorial solution:
this is $$$O(n^2)$$$ how tf did this solution passed?
I was thinking that too. But the submission took 703ms, well below the 2s limit.
Yeah, I saw people in contest get AC with O(n^2) solutions as well, maybe if there were hacks they could potentially get TLE. I used a Segment Tree to track the positions lol.
_R00T eren__ sweetweasel Hamed_Ghaffari
Please pin announcement and editorial to the contest.
For B, can we prove that there are only 2 cycles possible. I ran the simutation and yes those are the only set of possible values after like 50 operations, but is there a proof for it?
try to prove it by yourself
?? Obviously I've already spent good enough time trying to prove it but couldn't
For sufficiently large $$$n$$$ the number after the operation will always be smaller than before, after computationally verifying for small $$$n$$$ we can use strong induction
Yes, there are 1e9 elements which are reduced to 729, so there must be cycles happening inside this. But can we prove that there are exactly 2 cycles without using bruteforce?
I don't see any other way, brute forcing for small $$$n$$$ and strong induction for sufficiently large is a valid proof
Hi, wanna-be-HIM, also can't prove it :( But you can look at my comment. I came up with a preprocessing method only takes $$$O(num\ of\ states)$$$, and we don't need to prove the number of cycles or the lengths ourselves.
My Solution to D: KINDA BRUTE FORCE BUT SUBTLE - The XOR of any a[i] with any other number x in the constraints of the problem is always < 16. - It's given in the problem that you can XOR a[i] and a[i+1] with 3*k. Where 1 <= k <= 5. - This means that the possible XORs candidates to XOR the elements with is set st = {3,6,9,12,15}. - So if we make a combination of many operations per pair (a[i], a[i+1]), then it is like XORing with one of the many XOR combinations of st. For example I can make operations on a pair first with 3, then 6, then probably 15. So it's like the combination of any number of elements in the set st. And then finally XOR this combination result with the pair (a[i], a[i+1]) - Obviously it is of no use to use the same element to XOR again and again cuz it doesnt change the result of the final XOR of the two elements in any way. - An interesting observation is that any combination of the XORs will only give you numbers in the set num = {0,3,5,6,9,10,12,15}. And also, it can be seen that only elements in the array which already belong to the set num can be ever made to be divisible by 3. All the others will never give any result divisible by 3. You can simply test this out by taking all the numbers from 1 — 15 and then XORing it with the elements in the num set. - So the algorithm is fairly simple now, keep a present[] array which tracks the elements in the array which are present in the num set; 1 for present and 0 for not present. Have a ctr variable initialized to the number of elements in the array which belong the set. If at the qth query we replace an element in the array which is 1 in that index in the present array with an element which is not present in the num set, then decrease the ctr by 1. If at the qth query we replace an element in the array which is 0 in that index in the present array with an element which is present in the num set, then increase the ctr by 1.
Here's my code:
392366386
During the contest, I felt that for Problem B, the values would enter a cycle very quickly, so I wrote a brute-force function to check whether two numbers would eventually become equal. The logic is simple: just simulate both of them for 100 iterations, and then iterate over all pairs.
Problem B could have had a better reading code and a less complicated explanation.
Was it just me or was d1C editorial written by chatgpt again :sob:
Anyway even though I got cooked by it I think it's a pretty good problem, yeah there's a huge gap but whatever. The only complaint I have is that once I read a few hints I found a n log^3 (log from binsearch, log from small to large, and another log from I was planning to use std::set to do the prefix xor stuff). Removing that log factor felt like yet another hurdle to jump through (though I will admit that the way to do it by only doing frequency array on the big side so you don't run out of memory is pretty interesting to me)
On F you can reject a grid before building any moves. Xor the inversion parity of every column. A 2x2 swap always flips two columns, so that xor never changes, and a sorted grid is 0. If you start at 1, it's -1.
Div 2 E can be solved via bitwise xor prefix sums right ? (From msb to lsb try to find a range that has this bit and already fixed bits counts as odd , from this result fix or dont fix this bit).
This approach is a lot simpler in my opinion and tiny bit more implementation.
I spent 30 minutes reading 2E only to comeback do 2D to brute and solve it after 15 minutes lol. Typical DNC problem, I have never be able to solve it in strict contest time lol
Div2 F, vec needn't be an array of vectors. it can just be an array. This confused me so much.
For Div1E, standard 3-NTT convolution can squeeze in the time limit with a fast enough template, which skips most of the problem's difficulty.
garbo round
For A : Delay the first withdrawal as much as possible while still leaving enough days to perform the remaining (k-1) withdrawals, then withdraw every day until the bank closes.
For 2269C — K Is Important / 2268A — K Is Important
PS:- Took this idea from cses Problem set , seemed very intuative to me
Problem D is quite simple, but the thinking process really made me feel awkward.
$$$O(b \, n \log^2 n)$$$ is not supposed to pass for E?