Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) E 贪心

http://codeforces.com/contest/967/problem/E

 

Topic meaning:

gives you an array a of length n

Fixed: b (i) = a (1) ^ a (2) ^ ...... ^ a (i),

Ask, is there a situation such that after a(i) is rearranged, b(i) is strictly monotonically increasing.

 

Ideas:

For binary bit operations, if the XOR value increases, that is, p^q > p, two conditions must be satisfied (assuming one is p and the other is q)

①The highest bit of q > the highest bit of p

②The highest bit of q (assuming the kth is the highest) < the highest bit of p, but the kth bit of p is 0

In this way, we are greedy to find it.

 

Each time, we greedily find the one that meets the conditions and has the smallest value.

// See if it will explode int! Will the array be one dimension less!
// The fetch problem must be careful of the conditions for the first mover to win
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 1e5 + 5;
int n;
vector<LL> ve;
vector<LL> bite;
vector<LL> G[maxn];
int pos[maxn];
int maxlen;

void get_bite(LL sum){
    bite.clear();
    while (sum){
        bite.pb(sum % 2);
        sum >>= 1;
    }
}

bool solve(){
    LL sum = 0;
    vector<LL> ans;
    for (int i = 1; i <= n; i++){
        get_bite(sum);
        bool flag = false;
        for (int j = 1; j <= maxlen; j++){
            if (j == bite.size()) continue;
            else if (j < bite.size() && (bite[j - 1] == 0)){
                if (G[j].size() > 0 && (G[j].size() > pos[j])){
                    flag = true;
                    ans.push_back(G[j][pos[j]]);
                    sum ^= G[j][pos[j]];
                    pos[j]++;
                    break;
                }
            }
            else if (j > bite.size()){
                if (G[j].size() > 0 && (G[j].size() > pos[j])){
                    flag = true;
                    ans.push_back(G[j][pos[j]]);
                    sum ^= G[j][pos[j]];
                    pos[j]++;
                    break;
                }
            }
        }
        if (!flag) return false;
    }
    puts("Yes");
    for (int i = 0; i < ans.size(); i++){
        printf("%lld ", ans[i]);
    }
    cout << endl;
    return true;
}

int main(){
    cin >> n;
    for (int i = 1; i <= n; i++){
        LL a; scanf("%lld", &a);
        ve.pb(a);
    }
    for (int i = 0; i < ve.size(); i++){
        LL tmp = ve[i];
        int cnt = 0;
        while (tmp){
            cnt++;
            tmp >>= 1;
        }
        G[cnt].pb(ve[i]);
        maxlen = max(maxlen, cnt);
    }
    for (int i = 1; i <= maxlen; i++){
        sort(ALL(G[i]));
    }
    if (solve() == false) puts("No");
    return 0;
}
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325087217&siteId=291194637