PRIMEREVERSE - Editorial

PROBLEM LINK:

Practice
Contest: Division 1
Contest: Division 2
Contest: Division 3
Contest: Division 4

Author: munch_01
Preparer: notsoloud
Testers: iceknight1093, satyam_343
Editorialist: iceknight1093

DIFFICULTY:

1053

PREREQUISITES:

None

PROBLEM:

You have two binary strings A and B of length N.
In one operation you can reverse any substring of A of prime length.

Is it possible to make A equal B?

EXPLANATION:

Clearly, a necessary condition to make A equal B in the end is for them to have equal numbers of 0's and 1's.

It turns out that this condition is also sufficient!
That is, it’s possible to make A equal B if and only if they have an equal number of zeros and ones.

Proof

Note that 2 is a prime, which means we’re allowed to swap adjacent elements.

This essentially allows to rearrange A however we like, so if A and B have the same number of zeros and ones we can make them equal; otherwise we can’t.

Checking this condition is easy: for example, you can iterate over A and B to compute the required counts in \mathcal{O}(N), or sort A and B and check whether they are equal.

TIME COMPLEXITY:

\mathcal{O}(N) per testcase.

CODE:

Preparer's code (C++)
#include <iostream> 
#include <string> 
#include <set> 
#include <map> 
#include <stack> 
#include <queue> 
#include <vector> 
#include <utility> 
#include <iomanip> 
#include <sstream> 
#include <bitset> 
#include <cstdlib> 
#include <iterator> 
#include <algorithm> 
#include <cstdio> 
#include <cctype> 
#include <cmath> 
#include <math.h> 
#include <ctime> 
#include <cstring> 
#include <unordered_set> 
#include <unordered_map> 
#include <cassert>
#define int long long int
#define pb push_back
#define mp make_pair
#define mod 1000000007
#define vl vector <ll>
#define all(c) (c).begin(),(c).end()
using namespace std;

const int N=500023;
bool vis[N];
vector <int> adj[N];
long long readInt(long long l,long long r,char endd){
    long long x=0;
    int cnt=0;
    int fi=-1;
    bool is_neg=false;
    while(true){
        char g=getchar();
        if(g=='-'){
            assert(fi==-1);
            is_neg=true;
            continue;
        }
        if('0'<=g && g<='9'){
            x*=10;
            x+=g-'0';
            if(cnt==0){
                fi=g-'0';
            }
            cnt++;
            assert(fi!=0 || cnt==1);
            assert(fi!=0 || is_neg==false);

            assert(!(cnt>19 || ( cnt==19 && fi>1) ));
        } else if(g==endd){
            if(is_neg){
                x= -x;
            }

            if(!(l <= x && x <= r))
            {
                cerr << l << ' ' << r << ' ' << x << '\n';
                assert(1 == 0);
            }

            return x;
        } else {
            assert(false);
        }
    }
}
string readString(int l,int r,char endd){
    string ret="";
    int cnt=0;
    while(true){
        char g=getchar();
        assert(g!=-1);
        if(g==endd){
            break;
        }
        cnt++;
        ret+=g;
    }
    assert(l<=cnt && cnt<=r);
    return ret;
}
long long readIntSp(long long l,long long r){
    return readInt(l,r,' ');
}
long long readIntLn(long long l,long long r){
    return readInt(l,r,'\n');
}
string readStringLn(int l,int r){
    return readString(l,r,'\n');
}
string readStringSp(int l,int r){
    return readString(l,r,' ');
}

void solve()
{
    int n = readIntLn(1, 100000);
    string s = readStringLn(1, n);
    string t = readStringLn(1, n);

    assert(s.size() == n);
    assert(t.size() == n);

    int s1 = 0, s2 = 0, t1 = 0, t2 = 0;

    for(int i = 0; i < n; i++){
        if(s[i] == '1')
            s1++;
        else
            s2++;

        if(t[i] == '1')
            t1++;
        else
            t2++;
    }

    if(s1==t1 && s2==t2){
        cout << "YES";
    }
    else{
        cout << "NO";
    }
}
int32_t main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL),cout.tie(NULL);
    int T=readInt(1,100,'\n');
    while(T--){
        solve();
        cout<<'\n';
    }
    assert(getchar()==-1);
    cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
}
Tester's code (C++)
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,unroll-loops")

#include <bits/stdc++.h>   
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;   
using namespace std;  
#define ll long long  
const ll INF_MUL=1e13;
const ll INF_ADD=1e18;    
#define pb push_back                 
#define mp make_pair          
#define nline "\n"                           
#define f first                                          
#define s second                                             
#define pll pair<ll,ll> 
#define all(x) x.begin(),x.end()     
#define vl vector<ll>           
#define vvl vector<vector<ll>>    
#define vvvl vector<vector<vector<ll>>>          
#ifndef ONLINE_JUDGE    
#define debug(x) cerr<<#x<<" "; _print(x); cerr<<nline;
#else
#define debug(x);  
#endif       
void _print(ll x){cerr<<x;}  
void _print(char x){cerr<<x;}   
void _print(string x){cerr<<x;}    
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());   
template<class T,class V> void _print(pair<T,V> p) {cerr<<"{"; _print(p.first);cerr<<","; _print(p.second);cerr<<"}";}
template<class T>void _print(vector<T> v) {cerr<<" [ "; for (T i:v){_print(i);cerr<<" ";}cerr<<"]";}
template<class T>void _print(set<T> v) {cerr<<" [ "; for (T i:v){_print(i); cerr<<" ";}cerr<<"]";}
template<class T>void _print(multiset<T> v) {cerr<< " [ "; for (T i:v){_print(i);cerr<<" ";}cerr<<"]";}
template<class T,class V>void _print(map<T, V> v) {cerr<<" [ "; for(auto i:v) {_print(i);cerr<<" ";} cerr<<"]";} 
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
typedef tree<pair<ll,ll>, null_type, less<pair<ll,ll>>, rb_tree_tag, tree_order_statistics_node_update> ordered_pset;
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const ll MOD=1e9+7;      
const ll MAX=500500;
void solve(){ 
    ll n; cin>>n;
    string l,r; cin>>l>>r;
    sort(all(l));
    sort(all(r));
    if(l==r){
        cout<<"YES\n";
    }  
    else{
        cout<<"NO\n";
    }
    return;                                
}                                                   
int main()                                                                                                
{      
    ios_base::sync_with_stdio(false);                         
    cin.tie(NULL);  
    #ifndef ONLINE_JUDGE                   
    freopen("input.txt", "r", stdin);                                              
    freopen("output.txt", "w", stdout);  
    freopen("error.txt", "w", stderr);                        
    #endif                          
    ll test_cases=1;               
    cin>>test_cases;
    while(test_cases--){
        solve();
    } 
    cout<<fixed<<setprecision(10);
    cerr<<"Time:"<<1000*((double)clock())/(double)CLOCKS_PER_SEC<<"ms\n"; 
}  
Editorialist's code (Python)
for _ in range(int(input())):
    n = int(input())
    a = sorted(input())
    b = sorted(input())
    print('Yes' if a == b else 'No')
1 Like

Similar to the solution provided in explanation, I used one counter to check how many ‘1’ are in first string and, for second string I used the condition to increment the counter if the value is ‘not equal to 0’.

Both should be the same condition right? , still in last test case is showed failure . Can anyone explain what i did wrong .

If you need help with a specific implementation, please link to your submission next time.

I assume you’re talking about this code, where the issue is that you read a string of length N into a character array of length N, when you should’ve been using a character array of length N+1, to account for the terminating character \0.
I’m not fully familiar with C but I think doing this causes undefined behavior, which happened to give you WA.

Simply fixing that to be size N+1 gets AC: submission