1849F - XOR Partition - CodeForces Solution


binary search bitmasks data structures divide and conquer greedy sortings trees

Please click on ads to support us..

C++ Code:

// g++ ".cpp" -o ""; cat "-in.txt" | & "..exe"
// g++ .cpp -std=c++17 -o  && time ./ < -in.txt
// g++-12 .cpp -O2 -std=c++17 -o  && time ./ < -in.txt
// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <cmath>
#include <ios>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <tuple>
#include <type_traits>
#include <chrono> 
#include <random>
#include <bitset>
#include <set>
#include <limits.h>
#include <list>
#include <stack>
#include <unordered_map>
#include <typeinfo>
#include <string.h>
#include <cstdint>
#include <numeric>
#include <cassert>
#include <sstream>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include <boost/lexical_cast.hpp>
// using boost::lexical_cast;
using namespace std;
using namespace __gnu_pbds;
// Policy based data structures
/*
    S.find_by_order(k) => returns iterator to the kth largest element
                        S.find_by_order(sz) returns end(S)
    S.order_of_key(x) => number of items in the set that are strictly smaller than x
*/
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T>
using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define endl "\n"
#define Re register
#define fori(i, s, n) for (Re int i = s; i < n; i++)
#define forii(i, s, n) for (Re int i = s; i > n; --i)
#define PB push_back
#define F first
#define S second
#define INF 0x3f3f3f3f
#define MINF 0x3f3f3f3f3f3f3f3fll
#define contain count
#define EB emplace_back
#define ld long double
#define ll long long
#define all(x) x.begin(), x.end()
#define foreach(x,in,s) for(const auto &x: s)
#define YES cout << "YES\n"
#define Yes cout << "Yes\n"
#define NO cout << "NO\n"
#define No cout << "No\n"
#define dbgx(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#define sp(x) fixed << setprecision(x) 
#define pi acos(-1.0)
#define some(a,l,r) a.begin()+l,a.begin()+(r+1)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define rng_seed(x) mt19937 rng(x)
#define uid(from,to) uniform_int_distribution<int>(from,to)
#define set(x, val) memset(x, val, sizeof(x))
#define urd(from,to) uniform_real_distribution<double>(from,to) int randint(int from=0,int to=1000000000){return uid(from,to)(rng);};
inline int popcount(int n) { return __builtin_popcount(n); }
inline int popcount(ll n) { return __builtin_popcountll(n); }
inline int lsb(int n) { return n != 0 ? __builtin_ctz(n) : -1; }
inline int lsb(ll n) { return n != 0 ? __builtin_ctzll(n) : -1; }
inline int msb(int n) { return n != 0 ? (31 - __builtin_clz(n)) : -1; }
inline int msb(ll n) { return n != 0 ? (63 - __builtin_clzll(n)) : -1; }
#define parity(n) __builtin_parityll(n)
#define lowerpos(a, x) (int)distance((a).begin(), lower_bound(all(a), x))
#define upperpos(a, x) (int)distance((a).begin(), upper_bound(all(a), x))
#define cube(n) cbrtl(n)
#define lg(n) __lg(n) + 1;
#define fast_io                   \
    ios_base::sync_with_stdio(0); \
    cin.tie(NULL);                \
    cout.tie(NULL);
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
    template<typename L, typename R>
    size_t operator()(pair<L,R> const& Y) const{
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(Y.first * 31ull + Y.second + FIXED_RANDOM);
    }
};

template <typename K, typename V>
using hash_table = gp_hash_table<K, V, custom_hash>;
// inline ll lread(){register ll x=0,f=1;register char c=getchar();while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;}
// inline int read(){register int x=0,f=1;register char c=getchar();while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;}

const int dx[4]{1, 0, -1, 0}, dy[4]{0, 1, 0, -1}; // for grid problems
const int MOD = 1e9 + 7;
const int MODD = 998244353;
const long double PI = 3.14159265358979323851280895940618620443274267017841L;
const long double E = 2.718281828459045235428168107993940338928950950503355L;
const double EPS = 1e-9;
template<typename Head, typename ...Tail>
void dbg_out(Head H, Tail... T) {
    cerr << ' ' << H;
    dbg_out(T...);
}
int low_set_bit(int x){return x&(-x);}
template <typename T> 
void sort_unique(vector<T>& v){ 
    sort(v.begin(), v.end());
    v.resize(unique(v.begin(), v.end()) - v.begin(), 0);        
    //v.erase(unique(v.begin(), v.end()), v.end()); 
}
bool check(int mask,int pos){return mask&(1<<pos);}
int ser(int mask,int pos){return mask|(1<<pos);}
int flip(int mask,int pos){return mask^(1<<pos);}
int reset(int mask,int pos){return mask&~(1 << pos);}
template<class T>
void self_max(T &a, T b) { if(a < b) a = b; }
template<class T>
void self_min(T &a, T b) { if(a > b) a = b; }
template<class T>
void self_add(T &a, T b) { a += b; if(a > MOD) a -= MOD; }
template<class T>
void self_sub(T &a, T b) { a -= b; if(a < 0) a += MOD; }
vector<string> split(const string &s, char delim) {
    vector<string> e; stringstream ss(s);string item;
    while(getline(ss, item, delim)) e.push_back(item);
    return e;
}
//   gcd(x,y)=gcd(x-y,y);
//   gcd(a,b,c.....,z)=gcd(a,b-a,c-a,......z-a);
//   gcd(a, lcm(b, c)) = lcm(gcd(a, b), gcd(a, c))
//   lcm(a, gcd(b, c)) = gcd(lcm(a, b), lcm(a, c)).
//   if p%x==0 && q%x==0 then (p%q)%x==0
template<typename T> 
T gcd(T a, T b) { if(b == 0) return a; return gcd(b, a%b); }
template<class T, class ...V>
void self_max(T &a, T b, V... c) { if(a < b) a = b; self_max(a, c...); }
template<class T, class ...V>
void self_min(T &a, T b, V... c) { if(a > b) a = b; self_min(a, c...); }
template<class T, class ...V>
void self_add(T &a, T b, V... c) { a += b; if(a > MOD) a -= MOD; self_add(a, c...); }
template<class T, class ...V>
void self_sub(T &a, T b, V... c) { a -= b; if(a < 0) a += MOD; self_sub(a, c...); }
// https://www.math.utah.edu/~schwede/MichiganClasses/math185/NotationAndTerminology.pdf
// (x0,y0) -> (x,y)
// x = x0 + b/gcd(a,b) * k      (∀ k∈Z)
// y = y0 - a/gcd(a,b) * k
// ax + by = d        where d = gcd(a,b)
// 33x + 17y = d
// you are denormalize the equation until you can't get b = 0.
// once you get b = 0. Then you will get x = 1, y = 1.
// 33(1) = 17(1) + 16
// 17(1) = 16(1) + 1
// 16(1) = 1(16) + 0
// 1(1) = 0(0) + 1
// generalize it as ax = b(-y) + d.
// Stop when we reach at b = 0 here x a will be our gcd. Then recursively calculate newx and newy from bottom to up to reach at our original equation.
// newx = oldy and newy = oldx - (b/a)*oldy;
inline ll extgcd(ll a, ll &x, ll b, ll &y){ if (b == 0) { x = 1, y = 0; return a; } ll gcd = extgcd(b, y, a % b, x); y -= a / b * x; return gcd;}
template<typename T = int>
inline int bin_pow(T n, T exp, T MOD = 1e9 + 7) { n %= MOD; ll res = 1; while(exp) { if(exp & 1) { res = (res * n) % MOD; } n = (n * n) % MOD; exp >>= 1;} return (res) % MOD;}
template<typename T>
inline double bin_powd(double n, T exp, double MOD = 1e9 + 7) { fmod(n, MOD); double res = 1.00; while(exp) { if(exp & 1) { res = fmod(res * n, MOD); } n = fmod(n * n, MOD); exp >>= 1;} return fmod(res, MOD);}
ll moduloMultiplication(ll a,ll b,ll mod){ll res = 0;a %= mod;while (b){if (b & 1)res = (res + a) % mod;b >>= 1;}return res;}
template<typename T>
inline ll modInverse(T a, T modd = 1e9+ 7) { ll x, y; ll g = extgcd(a,x,modd,y); /* ll res = (x % modd + modd) % modd; return res; */ return x;}

// https://cp-algorithms.com/algebra/linear-diophantine-equation.html#the-degenerate-case
//     ax + by = c.  (diaphantie equation)
// =>     ax = c (mod b)
// =>     by = c (mod a)
// =>     (a/d)x = (c/d) (mod b/d),  where d = gcd(a,b)
// =>     x = (c/d) inv(a/d) (mod b/d)
// =>    if c == d, then x = inv(a/d) mod(b/d). we can actually get inverse using modInverse1.
template<typename T>
inline ll modInverse1(T a, T modd = 1e9 + 7) { return bin_pow(a, modd-2, modd); }
template<typename T>
unordered_map<int,int> factorize(int x) { unordered_map<int,int> ans; int j = 2; while(x > 1) { if(x % j == 0) { int cnt = 0; while(x % j == 0) { cnt++; x /= j; } ans[j] = cnt; } j++;} return ans; }

// https://en.wikipedia.org/wiki/Chinese_remainder_theorem
// https://brilliant.org/wiki/chinese-remainder-theorem/
// a = a1(mod m1)
// a = a2(mod m2)
// solve m1x + m2y = gcd(m1,m2) using extgcd.
// a  =  ∑ ai* Mi * Ni           where Ni = product of all [m1,m2,...,mi-1,mi+1,..,mk] except mi. and Mi is the inverse of Ni.
//    k=1->n
ll chinese(ll a, ll m, ll b, ll n) { ll x, y; extgcd(a,x,b,y); a = a*n*(y + m) % m + b*m*(x + n) % m; if(a >= m*n) a -= m*n; return a;}
ll chinese_common(ll a, ll m, ll b, ll n) { ll d = gcd(m,n); if((b -= a % n) < 0) b += n; if(b % d) return -1; return d * chinese((ll)0, m / d, b / d, n / d) + a;}
constexpr int Z = 1e5 + 5;

void init_code(){
    fast_io;
    #ifdef LOCAL
        freopen("Input.txt", "r", stdin);
        freopen("Output.txt", "w", stdout);
        freopen("Error.txt", "w", stderr);
    #endif
}

#ifdef LOCAL
 
    #define deb(args...)       cerr << "[ " #args << " ] : " , debug(args);
    #define debx(args...)      (Debugger(" ")),args
    #define debug(args...)     (Debugger()) , args
 
    class Debugger
    {
        public:
        Debugger(const std::string& _separator = ", ") :
        first(true), separator(_separator){}
 
        template<typename ObjectType>
        Debugger& operator , (const ObjectType& v)
        {
            if(!first)
                std::cerr << separator;
            std::cerr << v;
            first = false;
            return *this;
        }
        ~Debugger() {  std::cerr << endl;}
 
        private:
        bool first;
        std::string separator;
    };
 
    template <typename T1, typename T2>
    inline std::ostream& operator << (std::ostream& os, const std::pair<T1, T2>& p)
    {
        return os << "(" << p.first << ", " << p.second << ")";
    }
 
    template<typename T>
    inline std::ostream &operator << (std::ostream & os,const std::vector<T>& v)
    {
        bool first = true;
        os << "[";
        for(unsigned int i = 0; i < v.size(); i++)
        {
            if(!first)
                os << ", ";
            os << v[i];
            first = false;
        }
        return os << "]";
    }
 
    template<typename T>
    inline std::ostream &operator << (std::ostream & os,const std::set<T>& v)
    {
        bool first = true;
        os << "[";
        for (typename std::set<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
        {
            if(!first)
                os << ", ";
            os << *ii;
            first = false;
        }
        return os << "]";
    }
 
    template<typename T>
    inline std::ostream &operator << (std::ostream & os,const std::multiset<T>& v)
    {
        bool first = true;
        os << "[";
        for (typename std::set<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
        {
            if(!first)
                os << ", ";
            os << *ii;
            first = false;
        }
        return os << "]";
    }
 
    template<typename T1, typename T2>
    inline std::ostream &operator << (std::ostream & os,const std::map<T1, T2>& v)
    {
        bool first = true;
        os << "[";
        for (typename std::map<T1, T2>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
        {
            if(!first)
                os << ", ";
            os << *ii ;
            first = false;
        }
        return os << "]";
    }
 
#else
 
    #define deb(args...)
    #define debx(args...)
    #define debug(args...)
 
#endif


void pre(){

}

const int MXN = 3000021;
int A[MXN], B[MXN], cnt[MXN], pref[MXN], suf[MXN];
int n, m, q, k, total, ans, l, r, b, c, d, x, y, best, last, low, high;
ll sum;
vector<pair<int,int>> C;
priority_queue<int, vector<int>, greater<int>> pq;
string s, t;
vector<pair<int,int>> vp;
set<pair<int,int>> sp;
set<string> ss;
unordered_map<string, int> mps;
unordered_map<int,int> mpi;
pair<int, int> a[MXN];
char color[MXN];

// void process(int l, int r) {
//     if(l == r) {
//         // do something
//         return;
//     }
//     int mid = l + (r - l) >> 1;
//     process(l, mid);
//     process(mid + 1, r);
// }

// void solve(){
//     cin >> n;

//     fori(i, 0, n) {
//         cin >> A[i];
//     }

//     process(0, n - 1);
// }

void solve(){
    cin >> n;
    for(Re int i = 1; i <= n; i ++ ){
        cin >> a[i].first;
        a[i].second = i, color[i] = '0';
    }
 
    sort(a + 1, a + n + 1);
    
    function<int(int, int, int)> dfs = [&](int l, int r, int d) -> int {
        if(l > r) return (1 << 30);
        if(d < 0) return 0;
 
        Re int mid = l - 1;
        while(mid + 1 <= r && !(a[mid + 1].first >> d & 1)) mid ++ ;
        if(mid - l + 1 >= 5 || r - mid >= 5)
            return min(dfs(l, mid, d - 1), dfs(mid + 1, r, d - 1));
 
        Re int cnt = r - l + 1;
        Re int ans = -1, state = 0;
        for(Re int i = 0; i < (1 << cnt); i ++ )
        {
            int res = (1 << 30);
            for(Re int j = 0; j < cnt; j ++ )
            {
                int b1 = (i >> j & 1);
                for(Re int k = j + 1; k < cnt; k ++ )
                {
                    int b2 = (i >> k & 1);
                    if(b1 == b2)
                        res = min(res, a[l + j].first ^ a[l + k].first);
                }
            }
 
            if(res > ans)
            {
                ans = res;
                state = i;
            }
        }
 
        for(Re int i = 0; i < cnt; i ++ )
            if(state >> i & 1) color[a[l + i].second] = '1';
        return ans;
    };
 
    dfs(1, n, 30);
    cout << color + 1 << '\n';
}

signed main()
{
    fast_io;
    init_code();
    pre();
    cout << fixed << setprecision(6);
    // auto begin = chrono::high_resolution_clock::now();
    ll T = 1;
    // cin >> T;
    while (T--)
    {
        // cout << "Case #" << T << ": ";
        solve();
        // cout << endl;
        // auto end = chrono::high_resolution_clock::now();
        // auto duration = chrono::duration_cast<chrono::milliseconds> (end - begin).count();
        // cout << duration << " ms elapsed" << endl;
    }
    return 0;
}


Comments

Submit
0 Comments
More Questions

1271A - Suits
259B - Little Elephant and Magic Square
1389A - LCM Problem
778A - String Game
1382A - Common Subsequence
1512D - Corrupted Array
667B - Coat of Anticubism
284B - Cows and Poker Game
1666D - Deletive Editing
1433D - Districts Connection
2B - The least round way
1324A - Yet Another Tetris Problem
246B - Increase and Decrease
22E - Scheme
1566A - Median Maximization
1278A - Shuffle Hashing
1666F - Fancy Stack
1354A - Alarm Clock
1543B - Customising the Track
1337A - Ichihime and Triangle
1366A - Shovels and Swords
919A - Supermarket
630C - Lucky Numbers
1208B - Uniqueness
1384A - Common Prefixes
371A - K-Periodic Array
1542A - Odd Set
1567B - MEXor Mixup
669A - Little Artem and Presents
691B - s-palindrome