首页 > 其他分享 >Little Victor and Set 题解

Little Victor and Set 题解

时间:2023-09-21 19:55:35浏览次数:31  
标签:... Little Set int 题解 异或 add include red

Little Victor and Set

题目大意

在 \([l,r]\) 中选不超过 \(k\) 个相异的数使得异或和最小,输出方案。

思路分析

分类讨论:

  • 当 \(k=1\) 时:

显然选 \(l\) 是最优的。

  • 当 \(r-l+1\le 10\) 时:

直接 \(O(n2^n)\) 暴力枚举每个数选或不选即可。

(判了这个之后后面的很多讨论会简单很多。)

  • 当 \(k=2\) 时:

我们发现两个不同的数的异或和最小为 \(1\),因为当且仅当两个数相同时异或和为 \(0\)。

所以我们可以在 \([l,r]\) 内任找一个偶数 \(x\),那么方案就是 \(x\) 和 \(x+1\)。

(因为 \(r-l+1>10\) 所以一定能找到)

  • 当 \(k\ge 4\) 时:

容易发现对于任意 \(k\in N\),均有 \(4k\oplus(4k+1)\oplus(4k+2)\oplus (4k+3)=0\),所以我们只需要任取一个 \(k\) 就行了。

(因为 \(r-l+1>10\) 所以一定能找到)

  • 当 \(k=3\) 时:

首先,我们可以按照 \(k=2\) 的方法得到异或和为 \(1\) 的答案,我们只需要考虑是否存在异或和为 \(0\) 的方案即可。

我们枚举 \(i,j\,(i>j)\),构造 \(A=2^i+2^j,B=2^i+2^j-1,C=2^{j+1}-1\),容易发现 \(A\oplus B\oplus C=0,A>B>C\),考虑证明这样构造的合法性:

证明

我们只需要证明如果存在异或和为 \(0\) 的选法,一定存在一种选法满足以上的形式即可。

将 \(A,B,C\) 的二进制形式列出:

\[\begin{cases} A=00...00100...00100...00\\ B=00...00100...00011...11\\ C=00...00000...00111...11\\ \qquad\;\;\;\;{\color{red}^1}\;\;\;\;\; i\;\;\;\;\;{\color{red}^2}\;\;\;\;j\;\;\;\;{\color{red}^3}\end{cases}\]

当 \(A\) 固定时,\(C\) 不可能更大,因为当 \(C\) 增大时,\({\color{red}2}\) 部分会多出若干 \(1\),那么 \(B\) 就必须也在 \(2\) 部分增加若干 \(1\),那么 \(B\) 就大于 \(A\) 了,不符合题设。

若 \(A\) 的二进制表示中 \(1\) 的个数大于 \(2\),那么 \({\color{red}3}\) 部分会多出若干 \(1\),\(B,C\) 中必要有一个在对应的位置去掉若干个 \(1\) 来满足异或和为 \(0\) 的条件,故要么 \(B\) 变小要么 \(C\) 变小,如果这时的 \(A,C\) 在 \([l,r]\) 的范围内,那么之前的 \(A,C\) 也一定在 \([l,r]\) 的范围内。

若 \(A\) 的二进制表示中只有一个 \(1\),那么不存在满足条件的 \(B,C\)。

代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;
const int N = 200200, V = 40;
#define inf 0x3f3f3f3f3f3f3f3f
#define int long long

int l, r, k;

vector <int> ans;

void add(int x){
    ans.push_back(x);
}

template <typename types, typename... Args> void add(types x, Args... args){
    add(x), add(args...);
}

signed main(){
    cin >> l >> r >> k;
    if (k == 1) add(l);
    else if (r - l + 1 <= 10) {
        int len = r - l + 1, minans = inf, way = 0;
        for (int i = 1; i < (1ll << len); i ++) {
            int ans = 0, cnt = 0;
            for (int j = 0; j < len; j ++)
                if (i >> j & 1) {
                    ans ^= (l + j);
                    cnt ++;
                }
            if (cnt <= k && ans < minans) {
                minans = ans;
                way = i;
            }
        }
        for (int i = 0; i < len; i ++)
            if (way >> i & 1) add(l + i);
    }
    else if (k == 2) {
        if (l & 1) l ++;
        add(l, l + 1); 
    }
    else if (k == 3) {
        int flag = 0;
        for (int i = 0; i <= V && !flag; i ++) 
            for (int j = i + 1; j <= V; j ++) {
                int x = (1ll << i) | (1ll << j), y = x - 1, z = (x ^ y);
                if (x <= r && z >= l) {add(x, y, z); flag = 1; break;}
            }
        if (!flag) {
            if (l & 1) l ++;
            add(l, l + 1); 
        }
    }
    else if (k >= 4) {
        for (int i = l; i <= l + 4; i ++)
            if (i % 4 == 0) {
                add(i, i + 1, i + 2, i + 3); break;
            }
    }
    int res = 0;
    for (auto it : ans) res ^= it;
    cout << res << '\n';
    cout << ans.size() << '\n';
    for (auto it : ans) cout << it << ' ';
    return 0;
}

标签:...,Little,Set,int,题解,异或,add,include,red
From: https://www.cnblogs.com/TKXZ133/p/17720808.html

相关文章

  • docker搭建青龙面板及白屏问题解决方法
    最近也是想赚点小钱,搭建个青龙面包来挂脚本,但是在搭建过程中遇到过一些问题,所以记录下来。docker搭建青龙面板我这里是使用aliyun服务器进行搭建的,系统是centOS7.6版本。另外docker自行搜索安装即可。拉取青龙面板镜像远程登录服务器,输入命令拉取青龙镜像dockerpullwhyour......
  • 题解 P9019 [USACO23JAN] Tractor Paths P
    显然,对于给定的\(l,r\),最短路可以贪心求出,即每次走与当前区间相交且左端点最大的区间,这个可以用倍增加速。定义\(f_{i,j}\)表示从区间\(i\)往右走\(j\)步后到达的区间,\(g_{i,j}\)表示往左走的情况。正反遍历一下即可求出\(f_{i,1}\)和\(g_{i,1}\)。对于第二问,第\(i......
  • To_Heart—题解——好多好多!
    1.CF1860Dlink&&submission发现自己并不会处理纯纯的dp甚至自己根本不会dp!定义dp_{i,j,k}状态表示前i个字符有j个0,01的数量减去10的数量为k。转移比较显然了,答案是\(dp_{n,cnt0,0}\),其中cnt0是原序列中0的个数。注意k有正负。2.CF1860Flink.首先......
  • Win32编程之通过SetWindowsHookEx注入DLL(十六)
    一、SetWindowsHookEx函数SetWindowsHookEx是用于在Windows操作系统中设置全局或本地的钩子(hook)。钩子是一种用于监视并拦截特定事件或消息的机制,通常用于拦截和处理键盘输入、鼠标操作、窗口消息等。SetWindowsHookEx允许你安装一个全局或本地的钩子过程,以便在事件发生时执行......
  • STL(13) set multiset
    目录源码VC6中没有identity()那么如何调用呢使用multiset有了红黑树的基础,set和map就变得很简单了源码一步一步的调用rbtree因为set的value就是key所以从value中取出key就用identity就可以而取出迭代器用的是constiterator不允许更改元素set呼叫底层rbtree所以也是一种......
  • 【UVA 12676】Inverting Huffman 题解(哈夫曼树)
    静态霍夫曼编码是一种主要用于文本压缩的编码算法。给出的文本为由N个不同字符组成的特定大小,算法选择N个代码,每个代码对应一个不同的字符性格使用这些代码压缩文本。为了选择代码,算法构建一个有N片叶子的二元根树。对于N≥2,树可按如下方式构建。1.对于文本中的每个不同字符,构......
  • 题解 UVA1537 Picnic Planning
    这道题在显然是最小生成树,但是很显然我是不会打最小生成树的。题意描述给定一张\(n\)个点\(m\)条边的无向图,求出无向图的一棵最小生成树,满足一号节点的度数不超过给定的整数\(s\)。具体思路首先,看到这种度数最多为\(s\)的题,显然想到wqs二分。但是wqs二分是恰好选......
  • Javascript中window.setInterval和window.setTimeout的区别
    在使用JScript的时候,我们有时需要间隔的执行一个方法,比如用来产生网页UI动画特效啥的。这是我们常常会使用方法setInterval或setTimeout,但是由于这两个方法是由脚本宿主模拟出来的Timer线程,在通过其调用我们的方法是不能为其传递参数。我们常用的使用场景是:代码如下:window.setTi......
  • 【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(四)
    ​贴接上回。。。 【往期FAQ参考】【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(一)【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(二)【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(三) 【本期FAQ】1、JS服务卡片能实现按钮触摸时更换背景色,离开恢复原来......
  • 【c&c++】C++中memset()函数的用法详解
    头文件:cstring 或 memory话说刚开始使用memset的时候一直以为memset是对每一个int赋值的,心里想有了memset还要for循环对数组进行初始化干嘛。但其实memset这个函数的作用是将数字以单个字节逐个拷贝的方式放到指定的内存中去memset(dp,0,sizeof(dp));int类型的变量一般占......