题意:给你一个集合,让你构造一个长度尽量长的排列,使得排列中任意相邻两个位置的数XOR后是集合中的数。

思路:我们考虑枚举i, 然后判断集合中所有小于1 << i的数是否可以构成一组异或空间的基,如果可以就可以通过深搜构造出来。判断的方法是通过高斯消元。找到最大的i,我们通过深搜的方式构造答案,深搜的时候通过枚举作为基的集合中的数来确定,这样相邻两个数之间的异或值一定是集合中的数。

标程中的找异或空间的算法有点奇特,先记录一下:

维护一个集合basis,是已经找到的基,加入一个新的数(x)时,在basis中从大到小,执行x = min(x, x ^ v) (v是basis中的元素),如果最后x不是0,那么x就是一个基底,插入basis。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 200010;
const int maxm = 2000010;
vector<int> ans, vec;
set<int> basis;
set<int> ::iterator it;
int ed;
bool v[maxm];
int a[maxn];
void add(int x) {//高斯消元
int tmp = x;
if(basis.size()) {
for (it = --basis.end();; it--) {
tmp = min(tmp, tmp ^ (*it));
if(it == basis.begin()) break;
}
}
if(!tmp) return;
basis.insert(tmp);
vec.push_back(x);
} void dfs(int x, int deep = 1) {
v[x] = 1;
ans.push_back(x);
if(deep == (1 << ed)) return;
for (int i = 0; i < vec.size(); i++) {
if(!v[x ^ vec[i]]) {
dfs(x ^ vec[i], deep + 1);
return;
}
}
} int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
sort(a + 1, a + 1 + n);
int pos = 1;
ed = 0;
for (int i = 1; i < 20; i++) {
for (; pos <= n && a[pos] < (1 << i); pos++)
add(a[pos]);
if(basis.size() == i) {
ed = i;
}
}
basis.clear();
vec.clear();
for (int i = 1; i <= n && a[i] < (1 << ed); i++)
add(a[i]);
dfs(0);
printf("%d\n", ed);
for (int i = 0; i < ans.size(); i++)
printf("%d ", ans[i]);
}

  

Codeforces 1163E 高斯消元 + dfs的更多相关文章

  1. Flip Game (高斯消元 || dfs)

    Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...

  2. BZOJ1770:[USACO]lights 燈(高斯消元,DFS)

    Description 貝希和她的閨密們在她們的牛棚中玩遊戲.但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了.貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望. ...

  3. [luoguP2962] [USACO09NOV]灯Lights(高斯消元 + dfs)

    传送门 先进行高斯消元 因为要求最少的开关次数,那么: 对于关键元,我们可以通过带入消元求出, 对于自由元,我们暴力枚举,进行dfs,因为只有开关两种状态,0或1 #include <cmath ...

  4. bzoj 1770: [Usaco2009 Nov]lights 燈【高斯消元+dfs】

    参考:https://blog.csdn.net/qq_34564984/article/details/53843777 可能背了假的板子-- 对于每个灯建立方程:与它相邻的灯的开关次数的异或和为1 ...

  5. Vasya and Shifts CodeForces - 832E (高斯消元)

    大意: 给定$4n$个$m$位的五进制数, $q$个询问, 每个询问给出一个$m$位的五进制数$b$, 求有多少种选数方案可以使五进制异或和为$b$. 高斯消元入门题 每次询问相当于就是给定了$m$个 ...

  6. POJ1288 Sly Number(高斯消元 dfs枚举)

    由于解集只为{0, 1, 2}故消元后需dfs枚举求解 #include<cstdio> #include<iostream> #include<cstdlib> ...

  7. Codeforces Gym10008E Harmonious Matrices(高斯消元)

    [题目链接] http://codeforces.com/gym/100008/ [题目大意] 给出 一个n*m的矩阵,要求用0和1填满,使得每个位置和周围四格相加为偶数,要求1的数目尽量多. [题解 ...

  8. BZOJ 2115 Wc2011 Xor DFS+高斯消元

    标题效果:鉴于无向图.右侧的每个边缘,求一个1至n路径,右上路径值XOR和最大 首先,一个XOR并能为一个路径1至n简单的路径和一些简单的XOR和环 我们开始DFS获得随机的1至n简单的路径和绘图环所 ...

  9. Codeforces 832E Vasya and Shifts - 高斯消元

    题目传送门 快速的传送门I 快速的传送门II 题目大意 (题意比较复杂,请自行阅读原题) 可以将原题的字母都看成它们的在字符表中的下标,这样问题就变成给定$n$个$m$维向量$\vec{a_{1}}, ...

随机推荐

  1. R2CNN论文思路记录

    Rotational region cnn 我们的目标是检测任意方向的场景文本,与RRPN类似,我们的网络也基于FasterR-CNN ,但我们采用不同的策略,而不是产生倾斜角度建议. 我们认为RPN ...

  2. Spring AOP中的JDK和CGLIB动态代理

    Spring在将Advice织入目标对象的Joinpoint是在运行时动态进行的.它采用的方式可能有两种,即JDK动态代理与CGLIB代理.Spring会根据具体的情况在两者之间切换. 实际情况如下: ...

  3. python3 利用configparser生成和读取配置文件

    利用configparser生成和读取配置文件 #Author by Andy #_*_ coding:utf-8 _*_ import configparser ''' 配置文件格式 groupna ...

  4. Vue项目中导入excel文件读取成js数组

    1. 安装组件 cnpm install xlsx --save 2. 代码 <template> <span> <input class="input-fil ...

  5. SpringBoot使用Swagger2搭建强大的RESTful API 文档功能

    swagger用于定义API文档. Swagger2的使用 Maven Plugin添加Swagger2相关jar包 <!--swagger2 start--> <dependenc ...

  6. MDK(keil)4.7中文注释乱码解决

    由于编码使用不统一导致别的开发环境下的文件在MDK(keil)下打开中文显示乱码,解决这一问题需要进行码制转换, 可以先将欲打开的文件转换成UTF-8格式(如在notepad中进行转换),也可以在打开 ...

  7. sql server 建表,增删改练习

    use master --drop database Class create database Class on primary( name='Class', filename='D:\SQLTes ...

  8. c++ 获取文件图标,类型名称,属性 SHGetFileInfo

    SHGetFileInfo是一个相当实用的Windows API函数. // [MoreWindows工作笔记4] 获取文件图标,类型名称,属性 SHGetFileInfo #include < ...

  9. 个人笔记 - C++相关收藏

    一.文件操作 1.C++从txt文件中读取二维的数组

  10. bp网络全解读

    https://blog.csdn.net/weixin_40432828/article/details/82192709