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;
}
相关推荐
To_OC5 小时前
LC 994 腐烂的橘子:人人都说是 BFS 入门题,我却写了三遍才过
javascript·算法·leetcode
金銀銅鐵9 小时前
[Python] 扩展欧几里得算法
python·数学·算法
To_OC11 小时前
LC 200 岛屿数量:经典 DFS 入门题,我第一次写居然连方向都搞错了
javascript·算法·leetcode
To_OC1 天前
LC 128 最长连续序列:别上来就排序,O (n) 解法才是这题的灵魂
javascript·算法·leetcode
05Kevin2 天前
lk每日冒险题--数据结构6.27
算法
To_OC2 天前
从一次栈溢出报错说起,我把递归彻底扒明白了
javascript·算法·程序员
千纸鹤安安2 天前
千问Qwen-AgentWorld来了:一个语言模型搞定七大Agent场景,GPT-5.4都输了
算法
七牛开发者2 天前
MCP 到底是什么?为什么 Agent 都想接上它
算法·aigc·agent