Problem - 2146D1 - Codeforces &&Problem - D2 - Codeforces

Problem - 2146D1 - Codeforces

题意很简单 给定一个从0开始的排列 b 重排b 得到a 使得sum(a|b)最大 b按顺序给出

首先 a|b 操作 我们可以看作a+b-a&b 那么我们只需要让所有的a&b 的和最小即可 观察样例发现 所有的答案都是(n+1)*n 所以我们猜测 存在一种重新排列的方式 使得所有的a&b =0

首先对于r=2^k-1 的情况 也就是 r的所有位置为1 的时候 我们可以直接对称进行构造

比如r=15 我们可以0于15 1与14 2与13 也就是(r-i)&i 一定为0 因为r全为1 r-i 就是去掉了i中为1 的部分 与i进行& 操作结果一定是 0 所以对于这种情况我们可以直接倒序输出

当r不等于2^k-1的时候 也就是会多一位最高位的时候 我们发现 最高位有1 的部分 如果去掉最高位 那么他们剩下的部分和低一位的时候没有区别

换句话说

01 2 3 4 5 6 7 他们本来是对称对称进行&的 全部为0 但是如果当前多了一个8 和9

8和9 去掉最高位后就是 0 和1 而0和1 本来就是和7 和6 进行&操作 所以我们可以令8 9 看作0 1 与7 6 进行&操作 然后剩下的部分重复这一过程即可

形式的 我们找到最高与r一致 并且所有位为1 的值m m-i 与i一定是&后为0 的 我们令i在(m-r 到r)范围 这样剩下的部分重复进行操作即可

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+5;
int a[N];
void solve(){
    int l,r;
    cin>>l>>r;
    int n=r-l+1;
    int r1=r;
    cout<<(r+1)*r<<'\n';
    while(r1>=0){
        int bit=0;
        int tmp=r1;
        while(tmp){
            tmp/=2;
            bit++;
        }
        int m=(1<<bit)-1;
        int st=m-r1;
        for(int i=st;i<=r1;i++){
            a[i]=m-i;
        }
        r1=st-1;
    }
    for(int i=0;i<n;i++){
        cout<<a[i]<<' ';
    }cout<<'\n';

}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)solve();    
    return 0;
}

Problem - D2 - Codeforces

D2不同的地方在于 起点不是l 但是我们依旧可以用类似的想法 如果存在一个位分界线 那么就按照分界线两侧一一匹配 然后剩下一部分没有分界线 最高位相同 这些相同的最高位是一定要舍弃的 因为数目多 所以我们可以直接 不看高位 看下一位 然后重复这个子问题进行求解

代码实现如下:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+5;
int L;
int g(int x,int j){
    return (x>>j)&1;
}
int get(int x){
    int num=0;
    while(x){
        x/=2;
        num++;
    }
    return num;
}
void dfs(int l,int r,vector<int>&ans,int j){
    if(l>r)return ;
    if(l==r){
        ans[l-L]=l;return ;
    }
    int mid=l;
    while(mid+1<=r&&g(mid+1,j)==g(l,j)){
        mid++;
    }
    if(mid==r){
        dfs(l,r,ans,j-1);
        return ;
    }
    int tl=mid+1,tr=mid;
    while(tl-1>=l&&tr+1<=r){
        tl--;tr++;
        ans[tl-L]=tr;
        ans[tr-L]=tl;
    }
    dfs(l,tl-1,ans,j-1);
    dfs(tr+1,r,ans,j-1);
}
void solve(){
    int l,r,res=0;;
    cin>>l>>r;
    L=l-1;
    vector<int>ans(r-l+2,0);
    dfs(l,r,ans,get(r)-1);
    for(int i=l;i<=r;i++){
        res+=(ans[i-L]|i);
    }
    cout<<res<<'\n';
    for(int i=l;i<=r;i++){
        cout<<ans[i-L]<<' ';
    }
    cout<<'\n';

}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)solve();    
    return 0;
}
相关推荐
Kk.08024 小时前
力扣 LCR 084.全排列||
算法·leetcode·职场和发展
环黄金线HHJX.4 小时前
龙虾钳足启发的AI集群语言交互新范式
开发语言·人工智能·算法·编辑器·交互
Omics Pro4 小时前
虚拟细胞:开启HIV/AIDS治疗新纪元的关键?
大数据·数据库·人工智能·深度学习·算法·机器学习·计算机视觉
旖-旎4 小时前
分治(快速选择算法)(3)
c++·算法·leetcode·排序算法·快速选择
_日拱一卒5 小时前
LeetCode:合并区间
算法·leetcode·职场和发展
汀、人工智能5 小时前
[特殊字符] 第3课:最长连续序列
数据结构·算法·数据库架构·图论·bfs·最长连续序列
少许极端5 小时前
算法奇妙屋(四十一)-贪心算法学习之路 8
学习·算法·贪心算法
Kethy__5 小时前
计算机中级-数据库系统工程师-数据结构-图
数据结构·算法·软考··数据库系统工程师·计算机中级
亿秒签到6 小时前
L2-007 家庭房产
数据结构·c++·算法