Codeforces-Round-827-Div-4-G-Orray


title: Codeforces Round 827 (Div. 4) G. Orray
date: 2023-04-06 21:48:25
categories:

  • Algorithm
  • Codeforces
    tags:
  • codeforces
  • 字典序
  • 排序
  • 贪心
  • 位运算
  • 1500

G. Orray

You are given an array 𝑎 consisting of 𝑛 nonnegative integers.

Let’s define the prefix OR array 𝑏 as the array 𝑏𝑖=𝑎1 𝖮𝖱 𝑎2 𝖮𝖱 … 𝖮𝖱 𝑎𝑖 , where 𝖮𝖱 represents the bitwise OR operation. In other words, the array 𝑏 is formed by computing the 𝖮𝖱 of every prefix of 𝑎 .

You are asked to rearrange the elements of the array 𝑎 in such a way that its prefix OR array is lexicographically maximum.

An array 𝑥 is lexicographically greater than an array 𝑦 if in the first position where 𝑥 and 𝑦 differ, 𝑥𝑖>𝑦𝑖 .

Input

The first line of the input contains a single integer 𝑡 (1≤𝑡≤100 ) — the number of test cases. The description of test cases follows.

The first line of each test case contains a single integer 𝑛 (1≤𝑛≤2⋅105 ) — the length of the array 𝑎 .

The second line of each test case contains 𝑛 nonnegative integers 𝑎1,…,𝑎𝑛 (0≤𝑎𝑖≤109 ).

It is guaranteed that the sum of 𝑛 over all test cases does not exceed 2⋅105 .

Output

For each test case print 𝑛 integers — any rearrangement of the array 𝑎 that obtains the lexicographically maximum prefix OR array.

题目大意

给你一个长度为n的非负整数数组,问你能不能重新排序,使得前缀异或数组是字典序最大的。

思路

这题我看错题目了,一开始以为是异或操作,所以就想的复杂了。

因为两个数会进行或操作,在或运算中,有1得1,全0为0,所以两个数进行或运算只会变大,而不会变小。

假设当前的前缀或为res,因为要想让数变大,所以我们肯定会尽可能多选能让res变大的数,这个过程最多只会进行30次,因为 a i a_i ai最大为 1 0 9 10^9 109,因此我们最多会进行 m i n ( n , 30 ) min(n,30) min(n,30)次排序,选出我们想要的数,剩下的任意输出就可以了。

代码

#include <bits/stdc++.h>

#define int long long
using namespace std;
int res = 0;

bool cmp(int a, int b) {
    return (res | a) > (res | b);
}

void solve() {
    res = 0;
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) cin >> a[i];

    int cnt = min((long long) 30, n);
    for (int i = 1; i <= cnt; i++) {
        sort(a.begin() + i, a.end(), cmp);
        res |= a[i];
    }
    for (int i = 1; i <= n; i++) {
        cout << a[i] << " \n"[i == n];
    }
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("../test.in", "r", stdin);
    freopen("../test.out", "w", stdout);
#endif
    int _;
    cin >> _;
    while (_--) solve();

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重生之我是cxk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值