[题解]CF1742G Orray

思路

做这道题之前,首先要知道一个性质:aorba。那么,我们就能得出一个结论:经过一定顺序的排列,最多经过 log2amax 个数就能让前缀或的值达到最大值。

我们不妨令有一个位置 ib1,b2,,bi1 单调递增,而 bi=bi+1==bn

那么,根据上面的结论,我们可知 i 的最大值一定为 log2amax

因此,我们可以从 130 枚举(因为 0ai109,所以,log2amax=30),每一次选出能使或值变得最大的一个数排在重拍后的 a 数组的前面(排在上一次选出的数的后面)。

但是,我们选的时候有可能有剩下的数,那该怎么办呢?由于,我们参考的是重拍后的 a 的前缀或和。既然这时的或和已经到了最大值,根据或的性质,后面无论怎么加数改它都不会变了。

其实,我们可以直接选出第一位的数,显而易见的是,第一位一定是为:amax。因为,0oramax 是最大的。

我们来分析一下时间复杂度为:Θ(30NT)

Code

#include <bits/stdc++.h>  
#define re register  
  
using namespace std;  
  
const int N = 2e5 + 10;  
int T,n,idx,res;  
int arr[N],ans[N];  
  
inline int read(){  
    int r = 0,w = 1;  
    char c = getchar();  
    while (c < '0' || c > '9'){  
        if (c == '-') w = -1;  
        c = getchar();  
    }  
    while (c >= '0' && c <= '9'){  
        r = (r << 3) + (r << 1) + (c ^ 48);  
        c = getchar();  
    }  
    return r * w;  
}  
  
inline int cmp(int a,int b){  
    return a > b;  
}  
  
int main(){  
    T = read();  
    while (T--){  
        idx = res = 0;  
        n = read();  
        for (re int i = 1;i <= n;i++) arr[i] = read();  
        sort(arr + 1,arr + 1 + n,cmp);//排序便于找最大值   
        ans[++idx] = res = arr[1];//直接确定第一位   
        arr[1] = -1;//把取过的数标记为 -1   
        for (re int i = 1;i <= 31;i++){  
            int Max = res;  
            int id = -1;  
            for (re int j = 1;j <= n;j++){//暴力枚举   
                if (~arr[j]){//如果取过了便不能再取了   
                    if (Max < (res | arr[j])){//判断新的值是否能超过之前的最大值   
                        Max = res | arr[j];//是,更新   
                        id = j;//更新位置   
                    }  
                }  
            }  
            if (~id){//如果有数被取出过   
                res = Max;//更新当前的或值   
                ans[++idx] = arr[id];//添加到答案数组中   
                arr[id] = -1;//记得标记   
            }  
            else break;//直接提前结束   
        }  
        for (re int i = 1;i <= idx;i++) printf("%d ",ans[i]);//先输出被取出过的   
        for (re int i = 1;i <= n;i++){  
            if (~arr[i]) printf("%d ",arr[i]);//把没选出过的输出出来   
        }  
        puts("");  
    }  
    return 0;  
}  

作者:WaterSun

出处:https://www.cnblogs.com/WaterSun/p/18264809

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   WBIKPS  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示