虽然做起来有一点裸……但是就是想不到啊……

首先令 $d_i=p_i\oplus p_{i-1}$,那么 $d_i$ 都是 $S$ 中的数,$a_i=d_i\oplus d_{i-1}\oplus \cdots\oplus d_2$。也就是每个数都能被表示成 $S$ 的某个子集的异或和。

要用 $S$ 表示出 $1$ 到 $2^x-1$ 的所有数(不用考虑 $0$,因为每个数是可以重复用的,可以 $S_i\oplus S_i=0$)。怎么求出最大的 $x$?

其实就是建出线性基,然后最小的没有数的位就是 $x$ 了。为什么?当 $0$ 到 $x-1$ 都有数时是可以表示出所有 $0$ 到 $2^x-1$ 的,而当 $x$ 没有数时无法填第 $x$ 位。

(想用严谨一点的语言的……然而实力不允许……)

然后,求出 $x$ 后如何构造排列?

首先有最原始的想法:DFS,每次 $O(n)$ 枚举下一个数是这一个数异或上啥。肯定不可能过。

然后发现只需要保留线性无关的最大子集(可以在建线性基的过程中就完成),此时肯定还是能表示出全部的数(线性无关的定义)。同时数的个数降到了 $O(\log)$。

看起来还是不能过,但是……它的复杂度是对的!为什么?

DFS 过程中要判断 $vis[x\oplus S[i]]$,这就是在原始想法中耗费大量无用时间的原因。

而出现这样的情况,当且仅当出现了区间异或和为 $0$ 的情况。

但是对于这个线性无关的子集,会出现这样的情况,当且仅当当前枚举的 $S_i$ 等于目前的某一个后缀异或和。因为既然线性无关,所以所有不可重子集的异或和都不为 $0$。

由于 $S_i$ 只有 $O(\log)$ 种,所以也只会有 $O(\log)$ 次无法递归。

那么复杂度就对了。$O(n\log)$。下面的代码实现比较丑,所以复杂度似乎是两个 $\log$。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=;
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return f?-x:x;
}
int n,s[maxn],lb[],vec[],vl,ans,seq[maxn],sl;
bool vis[maxn],ok;
void insert(int x){
int tmp=x;
ROF(i,,) if((x>>i)&){
if(!lb[i]){
lb[i]=x;
vec[++vl]=tmp;
return;
}
else x^=lb[i];
}
}
bool check(int x){
FOR(i,,x-) if(!lb[i]) return false;
return true;
}
void dfs(int x){
vis[x]=true;
seq[++sl]=x;
if(sl==(<<ans)){ok=true;return;}
FOR(i,,vl) if(!vis[x^vec[i]]){
dfs(x^vec[i]);
if(ok) return;
}
vis[x]=false;
sl--;
}
int main(){
n=read();
FOR(i,,n) s[i]=read();
ROF(_,,){
MEM(lb,);MEM(vec,);vl=;
FOR(i,,n) if(s[i]<=(<<_)-) insert(s[i]);
if(check(_)){ans=_;break;}
}
printf("%d\n",ans);
dfs();
FOR(i,,sl) printf("%d ",seq[i]);
}

CF1163E Magical Permutation(线性基,构造)的更多相关文章

  1. Codeforces 1163E Magical Permutation [线性基,构造]

    codeforces 思路 我顺着图论的标签点进去的,却没想到-- 可以发现排列内每一个数都是集合里的数异或出来的. 考虑答案的上界是多少.如果能用小于\(2^k\)的数构造出\([0,2^k-1]\ ...

  2. CF1163E Magical Permutation【线性基,构造】

    题目描述:输入一个大小为\(n\)的正整数集合\(S\),求最大的\(x\),使得能构造一个\(0\)到\(2^x-1\)的排列\(p\),满足\(p_i\oplus p_{i+1}\in S\) 数 ...

  3. 51Nod1577 异或凑数 线性基 构造

    国际惯例的题面:异或凑出一个数,显然是线性基了.显然我们能把区间[l,r]的数全都扔进一个线性基,然后试着插入w,如果能插入,则说明w不能被这些数线性表出,那么就要输出"NO"了. ...

  4. CF1163E Magical Permutation

    题意:给定集合,求一个最大的x,使得存在一个0 ~ 2x - 1的排列,满足每相邻的两个数的异或值都在S中出现过.Si <= 2e5 解:若有a,b,c,令S1 = a ^ b, S2 = b ...

  5. BZOJ3569: DZY Loves Chinese II(线性基构造)

    Description 神校XJ之学霸兮,Dzy皇考曰JC. 摄提贞于孟陬兮,惟庚寅Dzy以降. 纷Dzy既有此内美兮,又重之以修能. 遂降临于OI界,欲以神力而凌♂辱众生.   今Dzy有一魞歄图, ...

  6. bzoj 4004 [JLOI2015]装备购买 拟阵+线性基

    [JLOI2015]装备购买 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1820  Solved: 547[Submit][Status][Dis ...

  7. Codeforces.472F.Design Tutorial: Change the Goal(构造 线性基 高斯消元)

    题目链接 \(Description\) 给定两个长为\(n\)的数组\(x_i,y_i\).每次你可以选定\(i,j\),令\(x_i=x_i\ \mathbb{xor}\ x_j\)(\(i,j\ ...

  8. 【HDU 3949】 XOR (线性基,高斯消元)

    XOR Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  9. 高斯消元 & 线性基【学习笔记】

    高斯消元 & 线性基 本来说不写了,但还是写点吧 [update 2017-02-18]现在发现真的有好多需要思考的地方,网上很多代码感觉都是错误的,虽然题目通过了 [update 2017- ...

随机推荐

  1. Oracle索引知识学习笔记

    目录 一.Oracle索引简介 1.1 索引分类 1.2 索引数据结构 1.3 索引特性 1.4 索引使用注意要点 1.5.索引的缺点 1.6.索引失效 二.索引分类介绍 2.1.位图索引 1.2.函 ...

  2. 一个动态构建 LambdaExpression Tree 的示例

    直接贴代码了: public class ExpressionTreeBuildingSampleTwo : Sample { public override string Name { get; } ...

  3. Oracle 原生驱动带来的精度问题的分析与解决

    问题 Oracle 官方提供了 dotnet core 驱动,但我们在使用中遇到了精度问题. 复现 以下代码运行数学运算 1/3,无论是 OracleCommand.ExecuteScalar() 还 ...

  4. MySQL5.8下载及安装——免安装版

    1.下载MySQL5.8下载地址:https://dev.mysql.com/downloads/mysql/ 图一: 图二: 2.如何安装.配置mysql-8.0.17-winx64.zip下载完成 ...

  5. yum 找不到程序,yum更换国内阿里源

    使用百度云服务器,发现百度yum源非常不稳定,果断采用阿里源,操作步骤如下: 一.备份 $ cd /etc/yum.repos.d/ $ mv baidu-bcm.repo baidu-bcm.rep ...

  6. conda opencv cv2.imshow无法使用

    error: -------src-dir-------/opencv-2.4.10/modules/highgui/src/window.cpp:501: error: (-2) The funct ...

  7. dubbo入门学习

    官方网址:http://dubbo.apache.org/zh-cn/index.html 学习可以参考官网中文文档:http://dubbo.apache.org/zh-cn/docs/user/q ...

  8. Java学习——反射

    Java学习——反射 摘要:本文主要讲述了什么是反射,使用反射有什么好处,以及如何使用反射. 部分内容来自以下博客: https://www.cnblogs.com/tech-bird/p/35253 ...

  9. SharpGL之Viewport

    视口变换主是将视景体内投影的物体显示到二维的视口平面上. 在计算机图形学中,它的定义是将经过几何变换, 投影变换和裁剪变换后的物体显示于屏幕指定区域内. 前面我们讨论过的透视投影, 正射投影, 它们都 ...

  10. amanda安装

    下载地址 http://www.amanda.org/download.php http://www.zmanda.com/download-amanda.php 编译安装 编译出错: error: ...