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

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

题目大意:

给你一个数组a,a的长度为n

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

问,是否存在一种情况,使得a(i)重新排列以后以后,满足b(i)是严格单调递增的。

思路:

对于二进制位操作来说,如果异或后值增加,即 p^q > p,必然满足两种情况(假定一个为p,一个为q)

①q的最高位>p的最高位

②q的最高位(假定第k为最高) < p的最高位,但是p的第k位为0

这样,我们就贪心的去找就好啦。

每次都贪心的找符合条件的,且value最小的即可。

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#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

猜你喜欢

转载自www.cnblogs.com/heimao5027/p/8973460.html