Thanks a lot for participating!
2267A - Turn Into a Palindrome
Solution
Tutorial is loading...
Implementation
#include <bits/stdc++.h>
using namespace std;
signed main() {
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
char c; cin >> c;
string s; cin >> s;
int ans = 0;
for (int i = 0; i < n / 2; ++i) {
if (s[i] == s[n - i - 1]) continue;
if (s[i] == c || s[n - i - 1] == c) ans++;
else ans+=2;
}
cout << ans << '\n';
}
}
Solution
Tutorial is loading...
Implementation
#include <bits/stdc++.h>
using namespace std;
int n, a[101], cnt[101];
void solve()
{
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
cnt[a[i]] ++;
}
for(int i = 1; i <= n; i ++)
{
for(int j = 100; j >= 1; j --)
{
if(cnt[j] >= i) cout << j << ' ';
}
}
for(int i = 1; i <= n; i ++) cnt[a[i]] = 0;
cout << '\n';
}
int main()
{
int t;
cin >> t;
while(t --) solve();
}
Solution
Tutorial is loading...
Implementation
#include <bits/stdc++.h>
#define ll long long
const int N = 3e5 + 12;
using namespace std;
int n, x, a[N], p[N];
ll cnt[N];
vector <int> vc[N];
void solve()
{
cin >> n >> x;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
int r = a[i];
a[i] = __gcd(a[i], x);
for(auto j : vc[a[i]])
{
cnt[j] += r;
}
}
ll ans = 0;
for(auto j : vc[x])
{
ans = max(ans, cnt[j]);
}
for(int i = 1; i <= n; i ++)
{
for(auto j : vc[a[i]]) cnt[j] = 0;
}
cout << ans << '\n';
}
signed main()
{
ios_base::sync_with_stdio(0), cin.tie(0);
for(int i = 2; i <= N - 12; i ++)
{
if(!p[i])
{
for(int j = i; j <= N - 12; j += i)
{
p[j] = 1;
vc[j].push_back(i);
}
}
}
int test = 0;
if(!test) cin >> test;
while(test --) solve();
}
// solved by KluydQ
Solution
Tutorial is loading...
Implementation
#include <bits/stdc++.h>
using namespace std;
void solve()
{
int n;
cin >> n;
int a[n + 5];
int pos[n + 5];
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
pos[a[i]] = i % 2;
}
int balance = 0;
for(int x = n; x > 0; x --)
{
if(pos[x] % 2 == 0) balance ++;
if(pos[x] % 2 == 1) balance --;
if(abs(balance) > 1)
{
cout << "NO\n";
return;
}
}
cout << "YES\n";
}
int main()
{
int t;
cin >> t;
while(t --) solve();
}
Solution
Tutorial is loading...
Implementation
#include <bits/stdc++.h>
#define int long long
#define sz(x) (int)(x.size())
#define FOR( i, x, n, d ) for( int i = x; i <= n; i += d )
#define FORR( i, x, n, d ) for( int i = x; i >= n; i -= d )
using namespace std;
const int N = 2e5 + 12;
const int mod = 1e9 + 7;
int n, q, ans, cnt0, cnt1, pr[N];
string s;
void solve()
{
cin >> n >> q >> s;
ans = cnt0 = cnt1 = 0;
FOR(i, 1, n - 1, 1)
{
pr[i] = 0;
if(s[i - 1] != s[i])
{
pr[i] = 1;
ans += i * (n - i);
}
}
FOR(i, 0, n - 1, 1)
{
if(s[i] == '0') cnt0 ++;
if(s[i] == '1') cnt1 ++;
}
cout << (ans + cnt0 * cnt1) / 2 << ' ';
FOR(i, 1, q, 1)
{
int pos;
cin >> pos;
if(pos != 1)
{
if(pr[pos - 1] == 0) pr[pos - 1] = 1, ans += (pos - 1) * (n - pos + 1);
else pr[pos - 1] = 0, ans -= (pos - 1) * (n - pos + 1);
}
if(pos != n)
{
if(pr[pos] == 0) pr[pos] = 1, ans += pos * (n - pos);
else pr[pos] = 0, ans -= pos * (n - pos);
}
if(s[pos - 1] == '0') cnt0 --, cnt1 ++, s[pos - 1] = '1';
else cnt1 --, cnt0 ++, s[pos - 1] = '0';
cout << (ans + cnt0 * cnt1) / 2 << ' ';
}
cout << '\n';
}
signed main()
{
ios_base::sync_with_stdio(0), cin.tie(0);
int t = 0;
if(!t) cin >> t;
while(t --) solve();
}
2267F1 - XOR Transformations (Easy Version)
Solution
Tutorial is loading...
Implementation
#include <bits/stdc++.h>
using namespace std;
const int N = 2048;
int n, m, tim, a[N], cnt[N], ans[N];
void transform()
{
vector <int> v;
for(int i = 1; i <= n; i ++)
{
for(int j = i + 1; j <= n; j ++)
{
v.push_back(a[i] ^ a[j]);
}
}
sort(v.begin(), v.end());
for(int i = 1; i <= n; i ++) a[i] = v[i - 1];
}
void solve()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
}
sort(a + 1, a + n + 1);
int lim = 0;
ans[lim] = a[n] - a[1];
while(a[n] != 0)
{
lim ++, transform();
ans[lim] = a[n] - a[1];
}
for(int i = 1; i <= m; i ++)
{
int x;
cin >> x;
if(x >= lim) cout << ans[lim] << '\n';
else cout << ans[x] << '\n';
}
}
signed main()
{
ios_base::sync_with_stdio(0), cin.tie(0);
int test = 0;
if(!test) cin >> test;
while(test --) solve();
}
2267F2 - XOR Transformations (Hard Version)
Solution
Tutorial is loading...
Implementation
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 12;
int n, m, tim, a[N], cnt[N], ans[N];
int t[N * 30], son[N * 30][2];
void update(int x, int v = 1)
{
t[v] ++;
for(int i = 29; i >= 0; i --)
{
if((x >> i) & 1)
{
if(!son[v][1]) son[v][1] = ++ tim;
v = son[v][1];
}
else
{
if(!son[v][0]) son[v][0] = ++ tim;
v = son[v][0];
}
t[v] ++;
}
}
int get(int x, int k, int v = 1)
{
int res = 0;
for(int i = 29; i >= 0; i --)
{
int b = (x >> i) & 1;
if(t[son[v][b]] >= k) v = son[v][b], res += (1 << i) * b;
else k -= t[son[v][b]], v = son[v][b ^ 1], res += (1 << i) * (b ^ 1);
}
return res ^ x;
}
void transform()
{
for(int v = 1; v <= tim; v ++) t[v] = son[v][0] = son[v][1] = 0;
set <pair <int, int>> st; tim = 1;
for(int i = 1; i <= n; i ++) update(a[i]), cnt[i] = 2;
for(int i = 1; i <= n; i ++) st.insert({get(a[i], 2), i});
vector <int> upd;
for(int _ = 1; _ <= 2 * n; _ ++)
{
auto it = st.begin();
int i = (*it).second;
upd.push_back((*it).first);
st.erase(it), cnt[i] ++;
if(cnt[i] > n) continue;
st.insert({get(a[i], cnt[i]), i});
}
for(int i = 1; i <= n; i ++) a[i] = upd[(i - 1) * 2];
}
void solve()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
}
sort(a + 1, a + n + 1);
int lim = 0;
ans[lim] = a[n] - a[1];
while(a[n] != 0)
{
lim ++, transform();
ans[lim] = a[n] - a[1];
}
for(int i = 1; i <= m; i ++)
{
int x;
cin >> x;
if(x >= lim) cout << ans[lim] << '\n';
else cout << ans[x] << '\n';
}
}
signed main()
{
ios_base::sync_with_stdio(0), cin.tie(0);
int test = 0;
if(!test) cin >> test;
while(test --) solve();
}
Solution
Tutorial is loading...
Implementation
#include <bits/stdc++.h>
#define sz(x) (int)(x.size())
#define FOR( i, x, n, d ) for( int i = x; i <= n; i += d )
#define FORR( i, x, n, d ) for( int i = x; i >= n; i -= d )
using namespace std;
const int N = (1 << 20) + 5;
const int mod = 1e9 + 7;
int n, m, c[N], dp[N], cnt[N], st[N][21];
void add(int &x, int y)
{
x += y;
if(x >= mod) x -= mod;
}
void solve()
{
cin >> n >> m;
FOR( i, 1, m, 1 )
{
cin >> c[i];
}
dp[0] = cnt[0] = 1;
FOR( i, 1, n, 1 )
{
st[i][0] = 0;
FOR( j, 0, 19, 1 )
{
st[i][j + 1] = st[i][j];
if(!((m >> j) & 1) || i < (1 << j)) continue;
else
{
add(st[i][j + 1], st[i - (1 << j)][j]);
add(st[i][j + 1], dp[i - (1 << j)]);
}
}
dp[i] = st[i][20];
}
FOR( i, 1, n, 1 )
{
st[i][0] = 0;
FOR( j, 0, 19, 1 )
{
st[i][j + 1] = st[i][j];
if(!((m >> j) & 1) || i < (1 << j)) continue;
else
{
add(st[i][j + 1], st[i - (1 << j)][j]);
add(st[i][j + 1], cnt[i - (1 << j)]);
}
}
cnt[i] = st[i][20];
add(cnt[i], dp[i]);
}
int ans = 0;
FOR( i, 1, m, 1 )
{
if((m & i) == i) add(ans, c[i] * 1ll * cnt[n - i] % mod);
}
cout << ans << '\n';
}
signed main()
{
ios_base::sync_with_stdio(0), cin.tie(0);
int t = 0;
if(!t) cin >> t;
while(t --) solve();
}








Auto comment: topic has been updated by KluydQ (previous revision, new revision, compare).
ORZ round. But in my opinion, C is harder than D.
Same, didn't even prove my approach for C, just went ahead with intuition.
Was able to do A and B
C really gave me a hard time
i should have worked on D instead of C...
F1 let me know that brute force is sometimes the solution
you didn't link the editorial in the original blog post
I feel like the problems in this round, except for G (which I couldn't solve), weren't that good.
Also, the extension from F1 to F2 is essentially an existing problem (https://qoj.ac/problem/2995), with an even better time complexity.
It has the same time complexity, isn’t it? Moreover, the crux of the problem was to understand that there is not more that $$$\log(A)$$$ transformations. Because of the fact that we need to do transformations +-9 times gives you greater time complexity.
Alright, I didn’t read the editorial, but the $$$O(\log^3)$$$ solution passed too.
I had a simpler solution for D.
Let's assume the array has an even length. Visually, if we "unfold" the hill and place it's elements in order it's gonna put all the outermost pairs A[i] and A[n-1-i] next to each other. This means that if we sort the initial array, in every pair A[2k] and A[2k+1] there must be one at an even position and one at an odd position, as one of them is gonna go to the left side and one to the right side, and their positions will have opposite parity. If the array has an odd length, we can just skip over the first element and solve for the rest of the array.
All you have to do in the implementation is sort the array and go through every pair where A[2k], A[2k+1] and check that their parities don't match. Fits in 15 lines.
Solved the same way using union find, I am still not able to understand how to come up with the solution given in the editorial.
shouldn't the Time Complexity of $$${C}$$$ be $$${O(n\cdot\sqrt[3]{x}+\sqrt{x})}$$$ ?
actually code works for $$$O(n\log(n) + 6n)$$$
oh your implementation is different, my bad!
No idea how my solution worked on F1, but I'm not complaining
Same , just relied on the solve count and gave it a shot. lol
C was much harder than D
C was simple: if
gcd(v[i],x)>1then we can take full of v[i] as v[i] will continously decresed by thegcdand it will remain same through this process...and if u think internallygcd will always be one of the divisor of x..and each divisor will give answer independently...so bruteforcing over each divisor individually and try to take as much as elements which are divisable as sum....ans will be the maximum sumwe can make use of this basic gcd proposition- gcd(ai,g)=gcd(ai-g,g)
most beautiful thing of this problem is that any divisor ultimately triggers its prime factors...so indeed we need to brute for each of the prime factors only
yes ofc, see, anyways g will always remain one of the prime factor of x i am just stating that the gcd will not gonna change even after decreasing ai
Also, my post-contest discussion stream for all problems is here
This round Felt like a div 3, especially F1 was really easy for a div 2.
I don't think it was quite intended for F2, but I solved it by dividing the intial array in many other arrays, each corresponding to a specific bitmask. From what I understand, it allows for my solution to have complexity $$$\frac{n^2}{const}$$$, instead of just $$$n^2$$$, where const can go > 2048. I also think it is highly amortized estimation.
E is so peak orz
In C instead of divisors, we can use prime divisors only ( this will give better time complexity) , check my code 392022818
F2=F1+Luogu P5283
For problem E, there is a more tedious solution (and with higher complexity)
Firstly, the contribution of a substring is the number of runs / 2, floored.
When a bit at s[x] (0-indexed) flips and s[x-1] == s[x+1], all substrings containing [x-1, x+1] will get a ±2 in number of runs depending on whether s[x-1] == s[x], which increases the answer by ± x * (n-x-1)
Then for substrings whose right or left boundary is x (inclusive of x), we need to find the number of bits that are equal to s[x-1] and s[x+1] on the left and right respectively, and call it cnt. This can be handled using a Fenwick/Segment Tree.
This logic applies similarly for the right side.
The initial calculation of the string can be viewed as inverting bits on a string that is originally filled with '0'
This is for when one could not make the observation over how we can separately handle cnt0 * cnt1 to be the number of odd sums. i would say E is a great problem.
392056887
Alternative solution to E: For a fixed string s, assume it starts with "1". The number of required operations will be the number of "10" substrings. This way, we don't have to deal with roundings. We can use segment tree to calculate the answer.
A at 250 and F1 at 1000 on the same round is a weird scoreboard. F1 did not feel 4 times harder than A.
Alternate Solution for C:
Notice that we need to find a subarray with $$$\gcd(x, a_{i_1}, a_{i_2}, \dots) \gt 1$$$ and the sum $$$(a_{i_1} + a_{i_2} + \dots)$$$ should be maximum. Now this $$$\gcd$$$ of a maximum sum array and $$$x$$$ will always be a multiple of a prime factor of $$$x$$$. So just do prime factorization of $$$x$$$ and for each prime factor of $$$x$$$, let's say $$$p$$$, iterate over the array and find the sum of the elements that are a multiple of $$$p$$$.
The distinct number of primes for $$$x \le 3 \cdot 10^5$$$ is not more than $$$7$$$, because $$$2 \cdot 3 \cdot 5 \cdot 7 \cdot 11 \cdot 13 \cdot 17 \gt 5 \cdot 10^5$$$. So overall Time complexity is $$$\mathcal{O}(\sqrt{x} + N)$$$.
any idea why this implementation gives TLE?: I think it should fit within the constraints
You are trying to find all divisors that too in O(x), you can find prime factors in O(sqrt(x)) and then proceed to simply check for divisibility by a single loop, my code for reference:
392023418
I can't prove why this works but here's a greedy approach (for problem D) that also construct such valid array configuration. Firstly we can divide the elements into odd and even indexed, and sort it. The main idea is to arrange the hill from the left by going back and forth between the odd and the even array (i.e. odd-even-odd..).
And if while doing so the placement isn't valid, we will place the element from the right (if it can't be placed in the left side of the hill, it has to be a part of the right side). After that we keep building from the left (if placement is valid). We can't build such valid configuration if placing the element in the right side won't work too.
Here's my solution 392111475
Here is a proof:
The left-most and right-most current blank on the two sides must by of one of the two types: T1 is where both blanks are of odd index or both blanks are of even index, and T2 means one blank is of odd index and the other is of even index. For convenience we call the two cases of T1 as T1O and T1E.
And we notice a few properties 1. Deaths (where it immediately can't build) can only happen on T1. Where both parity fails. In case of T2 you put it on the side with correct parity (your case where the left side can't be placed happens here). 2. T1 always changes into T2 when a new element is put into it, and vice versa (because placing an element changes the parity of the blank on one side).
When you finish then there is a valid configuration, which is trivial (you just constructed it). Now let's see why a case being stuck is not possible to avoid. First we would see that T1 always changes to T2 and T2 always changes to T1, so the time they appear won't change regardless of your actions (put on which side). Also in case of placing an element into T2, the board would force you to put it on exactly one side as the other side won't work (wrong parity), therefore the transition into T1O or T1E is also forced and not depending on your action. Therefore regarding the states of T1O, T1E, and T2, there is only one possibility regardless of your action. Your action only changes the direction where you put the numbers in, which does not affect death (since only T1O and T1E matters which does not depend on direction).
(I feel like there could've been a D2 that requires the count or requires a minimum cost construction in some way instead of keeping that C)
Here's my solution for D:
$$$pos[i]$$$ is the position of $$$i$$$ in the final array ($$$a_final[pos[i]] = i$$$)
Obeservation: You can permute the odd and even indices freely. So just care about the parity for $$$pos[i]$$$
$$$pos[n-1]$$$'s parity has 2 choices, $$$l$$$ and $$$r$$$ ($$$l == r$$$ and $$$l ≠ pos[n]$$$)
lets say $$$pos[i]$$$'s parity has 2 choices, $$$l$$$ and $$$r$$$