I hope you all liked the round. Please share your feedback in the comments section.
1747A — Two Groups
How about putting all positive numbers in one group and negative in second group
Let $$$S$$$ denotes sum of element of array $$$a$$$.
Claim: Answer is $$$|S|$$$.
Proof: Let sum of all positive elements is $$$S_{pos}$$$ and sum of all negative elements $$$S_{neg}$$$. Put all positive numbers in first group and negative numbers in second group. We get $$$||S_{pos}| - |S_{neg}|| = |S|$$$.
Let's prove that we can not do better than that. Let $$$S_1$$$ denotes sum of elements of first group and $$$S_2$$$ denotes sum of elements of second group. We have $$$|S_1| - |S_2| \leq |S_1 + S_2| = |S|$$$. Hence $$$|S|$$$ is the upperbound for the answer.
// Jai Shree Ram
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define ll long long
#define int long long
#define pb push_back
#define all(v) v.begin(),v.end()
#define endl "\n"
#define x first
#define y second
#define gcd(a,b) __gcd(a,b)
#define mem1(a) memset(a,-1,sizeof(a))
#define mem0(a) memset(a,0,sizeof(a))
#define sz(a) (int)a.size()
#define pii pair<int,int>
#define hell 1000000007
#define elasped_time 1.0 * clock() / CLOCKS_PER_SEC
template<typename T1,typename T2>istream& operator>>(istream& in,pair<T1,T2> &a){in>>a.x>>a.y;return in;}
template<typename T1,typename T2>ostream& operator<<(ostream& out,pair<T1,T2> a){out<<a.x<<" "<<a.y;return out;}
template<typename T,typename T1>T maxs(T &a,T1 b){if(b>a)a=b;return a;}
template<typename T,typename T1>T mins(T &a,T1 b){if(b<a)a=b;return a;}
int solve(){
int n; cin >> n;
int s = 0;
for(int i = 0; i < n; i++){
int x; cin >> x;
s += x;
}
cout << abs(s) << endl;
return 0;
}
signed main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#ifdef SIEVE
sieve();
#endif
#ifdef NCR
init();
#endif
int t=1;cin>>t;
while(t--){
solve();
}
return 0;
}
1747B — BAN BAN
Instead of subsequences solve for substrings. That is there should not be any substring $$$\texttt{BAN}$$$ after performing operations.
In one operation you can destroy atmost $$$2$$$ substrings. Find minimum operations to destroy $$$n$$$ substrings.
$$$\left \lceil\frac{n}{2}\right \rceil $$$
Congrats, you have solved for subsequences also!
No subsequences of string $$$\texttt{BAN}$$$ would also mean no substrings of $$$\texttt{BAN}$$$ in original string. Let minimum number of operations to have no substrings of $$$\texttt{BAN}$$$ be $$$x$$$, it would be also be the lower bound for having no subsequences of string $$$\texttt{BAN}$$$.
Claim: $$$x = \left \lceil\frac{n}{2}\right \rceil$$$.
Proof: Swap $$$i$$$-th $$$\texttt{B}$$$ from start with $$$i$$$-th $$$\texttt{N}$$$ from end for $$$1 \leq i \leq \left \lceil\frac{n}{2}\right \rceil$$$. We can see that, no substrings of $$$\texttt{BAN}$$$ exists after performing $$$ \left \lceil\frac{n}{2}\right \rceil$$$ operations. Since we can only destroy atmost $$$2$$$ substrings in one operations, $$$\left \lceil\frac{n}{2}\right \rceil$$$ is minimum possible.
Now if you see clearly, after performing above operations, there does not exist any subsequence of string $$$\texttt{BAN}$$$ in original string. Hence $$$\left \lceil\frac{n}{2}\right \rceil$$$ is also the answer for the original problem.
// Jai Shree Ram
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define ll long long
#define int long long
#define pb push_back
#define all(v) v.begin(),v.end()
#define endl "\n"
#define x first
#define y second
#define gcd(a,b) __gcd(a,b)
#define mem1(a) memset(a,-1,sizeof(a))
#define mem0(a) memset(a,0,sizeof(a))
#define sz(a) (int)a.size()
#define pii pair<int,int>
#define hell 1000000007
#define elasped_time 1.0 * clock() / CLOCKS_PER_SEC
template<typename T1,typename T2>istream& operator>>(istream& in,pair<T1,T2> &a){in>>a.x>>a.y;return in;}
template<typename T1,typename T2>ostream& operator<<(ostream& out,pair<T1,T2> a){out<<a.x<<" "<<a.y;return out;}
template<typename T,typename T1>T maxs(T &a,T1 b){if(b>a)a=b;return a;}
template<typename T,typename T1>T mins(T &a,T1 b){if(b<a)a=b;return a;}
int solve(){
int n; cin >> n;
cout << n/2 + n % 2 << endl;
int l = 1, r = 3*n;
while(l < r){
cout << l << " " << r << endl;
l += 3;
r -= 3;
}
return 0;
}
signed main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#ifdef SIEVE
sieve();
#endif
#ifdef NCR
init();
#endif
int t=1;cin>>t;
while(t--){
solve();
}
return 0;
}
1747C — Swap Game
Divide problem into two different cases. When $$$a_1 \gt \min(a)$$$ and when $$$a_1 = \min(a)$$$.
You do not need more hints to solve the problem.
Case 1: $$$a_1 \gt \min(a)$$$
$$$\texttt{Alice}$$$ can force the $$$\texttt{Bob}$$$ to always decrease the minimum element by always choosing minimum element of $$$a$$$ in her turn. Where as $$$\texttt{Bob}$$$ can not do much, all other elements he would swap with would be greater than or equal to $$$\min(a)$$$. Even if there exists multiple minimums in $$$a$$$, In first move $$$\texttt{Alice}$$$ would decrease from $$$a_1$$$, hence in this case $$$\texttt{Alice}$$$ would always win.
Case 2: $$$a_1 = \min(a)$$$
In this case optimal startegy for $$$\texttt{Bob}$$$ would be to always chhose minimum element of the array, which is $$$a_1$$$. $$$\texttt{Alice}$$$ would always be swapping the element greater than $$$a_1$$$ in her turn, hence in the case $$$\texttt{Bob}$$$ would always win
// Jai Shree Ram
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define ll long long
#define int long long
#define pb push_back
#define all(v) v.begin(),v.end()
#define endl "\n"
#define x first
#define y second
#define gcd(a,b) __gcd(a,b)
#define mem1(a) memset(a,-1,sizeof(a))
#define mem0(a) memset(a,0,sizeof(a))
#define sz(a) (int)a.size()
#define pii pair<int,int>
#define hell 1000000007
#define elasped_time 1.0 * clock() / CLOCKS_PER_SEC
template<typename T1,typename T2>istream& operator>>(istream& in,pair<T1,T2> &a){in>>a.x>>a.y;return in;}
template<typename T1,typename T2>ostream& operator<<(ostream& out,pair<T1,T2> a){out<<a.x<<" "<<a.y;return out;}
template<typename T,typename T1>T maxs(T &a,T1 b){if(b>a)a=b;return a;}
template<typename T,typename T1>T mins(T &a,T1 b){if(b<a)a=b;return a;}
int solve(){
int n; cin >> n;
vector<int> a(n);
for(auto &i:a)cin >> i;
sort(a.begin() + 1,a.end());
cout << (a[0] > a[1] ? "Alice" : "Bob") << endl;
return 0;
}
signed main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#ifdef SIEVE
sieve();
#endif
#ifdef NCR
init();
#endif
int t=1;cin>>t;
while(t--){
solve();
}
return 0;
}
1747D — Yet another Problem
Forget queries, they are just here to make problem look complicated. Solve for $$$q = 1$$$.
XOR of array does not change after operations. Hence if initially XOR is not equal to $$$0$$$, answer is $$$-1$$$. Is this condition sufficient?
No, We need one more condition
There must exist some prefix of odd size, such that xor of elements of that prefix is $$$0$$$.
First forget queries, solve for single array $$$a$$$.
Let's make some observations.
Xor of array does not change after each operation
Look at the set of prefix XORs while doing operations. Its size always decreases or remains same after each operation. Infact we can further reduce it to parities. Let $$$S_{0}$$$, $$$S_{1}$$$ be sets of prefix XOR's of parities $$$0$$$ and $$$1$$$ respectively. After each operation new sets $$$S'_{0}$$$, $$$S'_{1}$$$ will be subsets of $$$S_{0}$$$ and $$$S_1$$$ respectively.
So necessary conditions for answer to exist is that xor of array should be $$$0$$$ and $$$S_{1}$$$ should contains $$$0$$$.
Now comes to minimum operations.
Claim: If above conditions are satisfied, its always possible to make all elements $$$0$$$ in less than or equal to $$$2$$$ operations
Proof: Let length of array be $$$n$$$.
Case 1: $$$n$$$ is odd
Just apply the operation on whole array.
Case 2: $$$n$$$ is even
There will exists some odd size prefix $$$j$$$ such that xor of its elements is $$$0$$$. Apply operation on $$$[1,j]$$$ and $$$[j + 1,n]$$$. It can happen that $$$j = 1$$$ or $$$j = n - 1$$$, in that case we only need one operation, because other remaining element would already be equal to $$$0$$$.
To solve for queries, you just need to check for odd prefix, which can be done using some data structure like $$$\texttt{std::map}$$$ or $$$\texttt{std::set}$$$ in C++. Do not forget to check the case when all elements are already $$$0$$$.
#include<bits/stdc++.h>
using namespace std ;
#define ll long long
#define pb push_back
#define all(v) v.begin(),v.end()
#define sz(a) (ll)a.size()
#define F first
#define S second
#define INF 2000000000000000000
#define popcount(x) __builtin_popcountll(x)
#define pll pair<ll,ll>
#define pii pair<int,int>
#define ld long double
template<typename T, typename U> static inline void amin(T &x, U y){ if(y < x) x = y; }
template<typename T, typename U> static inline void amax(T &x, U y){ if(x < y) x = y; }
#ifdef LOCAL
#define debug(...) debug_out(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) 3000
#endif
int _runtimeTerror_()
{
int n, Q;
cin >> n >> Q;
map<int, int> odd, even;
vector<int> last_nz(n + 1, 0), last(n + 1, -1), pxor(n + 1, 0);
vector<int> a(n + 1);
even[0] = 0;
int cur = 0;
for(int i=1;i<=n;++i) {
cin >> a[i];
cur ^= a[i];
pxor[i] = cur;
if(a[i] == 0) {
last_nz[i] = last_nz[i - 1];
}
else {
last_nz[i] = i;
}
if(i & 1) {
if(even.count(cur)) {
last[i] = even[cur];
}
odd[cur] = i;
}
else {
if(odd.count(cur)) {
last[i] = odd[cur];
}
even[cur] = i;
}
}
while(Q--) {
int l, r;
cin >> l >> r;
if(pxor[l - 1] != pxor[r]) {
cout << "-1\n";
}
else if(last_nz[r] < l) {
cout << "0\n";
}
else if(r % 2 == l % 2) {
cout << "1\n";
}
else if(a[l] == 0 or a[r] == 0) {
cout << "1\n";
}
else if(last[r] >= l) {
cout << "2\n";
}
else {
cout << "-1\n";
}
}
return 0;
}
int main()
{
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#ifdef runSieve
sieve();
#endif
#ifdef NCR
initncr();
#endif
int TESTS = 1;
//cin >> TESTS;
while(TESTS--) {
_runtimeTerror_();
}
return 0;
}
1747E — List Generation
Will be availabe soon