CF1163E Magical Permutation
题意:给定集合,求一个最大的x,使得存在一个0 ~ 2x - 1的排列,满足每相邻的两个数的异或值都在S中出现过。Si <= 2e5
解:若有a,b,c,令S1 = a ^ b, S2 = b ^ c,则有a ^ c = S1 ^ S2
因为有0存在,所以每个数都能表示成它到0路径上的所有间隔的异或和,也就是每个数都能被表示出来。我们用线性基来判断。
找到最大的x之后,我们可以发现,线性基中x个数的2x种选法一一对应这2x个数。于是直接采用格雷码来找这个排列,每加一位,就在x个数中添加 / 删除一个数到异或集合中。
我的实现较复杂。实际上只要把线性基这x个数记下来,格雷码的时候选择是否异或即可。
#include <bits/stdc++.h>
const int N = ;
int n, a[N], base[], T, id[], sta[N], pos[N], s;
inline void clear() {
memset(base, , sizeof(base));
memset(id, , sizeof(id));
return;
}
inline void insert(int x, int v) {
int V = ;
for(int i = T - ; i >= ; i--) {
if(!((x >> i) & )) {
continue;
}
if(base[i]) {
x ^= base[i];
V ^= id[i];
}
else {
base[i] = x;
id[i] = V | ( << i);
break;
}
}
return;
}
inline bool check() {
for(int i = T - ; i >= ; i--) {
if(!base[i]) {
return false;
}
}
return true;
}
inline void find(int x) {
int t = x;
for(int i = T - ; i >= ; i--) {
if(!((x >> i) & )) {
continue;
}
x ^= base[i];
sta[t] ^= id[i];
}
return;
}
void DFS(int k) {
if(k == -) {
printf("%d ", pos[s]);
return;
}
DFS(k - );
s ^= << k;
DFS(k - );
return;
}
int main() {
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
}
std::sort(a + , a + n + );
int fin = ;
for(T = ; T <= ; T++) {
int lm = ( << T) - ;
clear();
for(int i = ; i <= n && a[i] <= lm; i++) {
insert(a[i], i);
}
if(check()) {
fin = T;
}
}
T = fin;
/// T
int lm = ( << T) - ;
for(int i = ; i <= lm; i++) {
find(i);
pos[sta[i]] = i;
}
printf("%d\n", T);
DFS(T - );
puts("");
return ;
}
AC代码
CF1163E Magical Permutation的更多相关文章
- CF1163E Magical Permutation(线性基,构造)
虽然做起来有一点裸……但是就是想不到啊…… 首先令 $d_i=p_i\oplus p_{i-1}$,那么 $d_i$ 都是 $S$ 中的数,$a_i=d_i\oplus d_{i-1}\oplus \ ...
- CF1163E Magical Permutation【线性基,构造】
题目描述:输入一个大小为\(n\)的正整数集合\(S\),求最大的\(x\),使得能构造一个\(0\)到\(2^x-1\)的排列\(p\),满足\(p_i\oplus p_{i+1}\in S\) 数 ...
- Codeforces 1163E Magical Permutation [线性基,构造]
codeforces 思路 我顺着图论的标签点进去的,却没想到-- 可以发现排列内每一个数都是集合里的数异或出来的. 考虑答案的上界是多少.如果能用小于\(2^k\)的数构造出\([0,2^k-1]\ ...
- Codeforces Round #558 (Div. 2)
目录 Codeforces Round #558 (Div. 2) 题解 A Eating Soup B Cat Party C Power Transmission D Mysterious Cod ...
- Permutation Sequence
The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...
- [LeetCode] Palindrome Permutation II 回文全排列之二
Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...
- [LeetCode] Palindrome Permutation 回文全排列
Given a string, determine if a permutation of the string could form a palindrome. For example," ...
- [LeetCode] Permutation Sequence 序列排序
The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...
- [LeetCode] Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
随机推荐
- Python实现字符串与数组相互转换功能示例
Python实现字符串与数组相互转换功能示例 本文实例讲述了Python实现字符串与数组相互转换功能.分享给大家供大家参考,具体如下: 字符串转数组 str = '1,2,3' arr = s ...
- 2019 牛客多校第二场 H Second Large Rectangle
题目链接:https://ac.nowcoder.com/acm/contest/882/H 题目大意 给定一个 n * m 的 01 矩阵,求其中第二大的子矩阵,子矩阵元素必须全部为 1.输出其大小 ...
- lasso数学解释
lasso:是L1正则化(绝对值) 注:坐标下降法即前向逐步线性回归 lasso算法:常用于特征选择 最小角算法,由于时间有限没有去好好研究(其实是有点复杂,尴尬)
- 大神给你分析HTTPS和HTTP的区别
今天在做雅虎的时候,发现用第三方工具截取不到客户端与服务端的通讯,以前重来没碰到过这种情况,仔细看了看,它的url请求时基于https的,gg了下发现原来https协议和http有着很大的区别.总的来 ...
- linux mysql 远程访问权限问题
1.为了让访问mysql的客户端的用户有访问权限,我们可以通过如下方式为用户进行授权:mysql> grant all on *.* to user_name@'%' identified by ...
- python学习8—函数之高阶函数与内置函数
python学习8—函数之高阶函数与内置函数 1. 高阶函数 a. map()函数 对第二个输入的参数进行第一个输入的参数指定的操作.map()函数的返回值是一个迭代器,只可以迭代一次,迭代过后会被释 ...
- USACO2006 Backward Digit Sums /// 全排列 oj24212
题目大意: 给出杨辉三角的顶点值M和底边数的个数 N (1 ≤ N ≤ 10) ,求出底边各个数的值,其中各个数范围都为1 ~ N 当N=4,M=16时可能是这样的 3 1 2 4 ...
- 【校OJ】选网线
暑假学校OJ上的题目. 一道很有意思的二分. 题意:三个数组,每个数组各选一个数出来看是否能组成目标数. 题解:前两个数组两两的和组合一下,二分第三个数组,找是否能组成目标数. 代码: #includ ...
- 006-Java的break和continue
break 和 continue关键字的使用 break: 结束当前循环 continue:结束当次循环 示例如下 class JavaTest{ public static void main(St ...
- netty UnpooledHeapByteBuf 源码分析
UnpooledHeapByteBuf 是基于堆内存进行内存分配的字节缓冲区,没有基于对象池技术实现,这意味着每次I/O的读写都会创建一个新的UnpooledHeapByteBuf,频繁进行大块内存的 ...