CF1163E Magical Permutation(线性基,构造)
虽然做起来有一点裸……但是就是想不到啊……
首先令 $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(线性基,构造)的更多相关文章
- Codeforces 1163E Magical Permutation [线性基,构造]
codeforces 思路 我顺着图论的标签点进去的,却没想到-- 可以发现排列内每一个数都是集合里的数异或出来的. 考虑答案的上界是多少.如果能用小于\(2^k\)的数构造出\([0,2^k-1]\ ...
- CF1163E Magical Permutation【线性基,构造】
题目描述:输入一个大小为\(n\)的正整数集合\(S\),求最大的\(x\),使得能构造一个\(0\)到\(2^x-1\)的排列\(p\),满足\(p_i\oplus p_{i+1}\in S\) 数 ...
- 51Nod1577 异或凑数 线性基 构造
国际惯例的题面:异或凑出一个数,显然是线性基了.显然我们能把区间[l,r]的数全都扔进一个线性基,然后试着插入w,如果能插入,则说明w不能被这些数线性表出,那么就要输出"NO"了. ...
- CF1163E Magical Permutation
题意:给定集合,求一个最大的x,使得存在一个0 ~ 2x - 1的排列,满足每相邻的两个数的异或值都在S中出现过.Si <= 2e5 解:若有a,b,c,令S1 = a ^ b, S2 = b ...
- BZOJ3569: DZY Loves Chinese II(线性基构造)
Description 神校XJ之学霸兮,Dzy皇考曰JC. 摄提贞于孟陬兮,惟庚寅Dzy以降. 纷Dzy既有此内美兮,又重之以修能. 遂降临于OI界,欲以神力而凌♂辱众生. 今Dzy有一魞歄图, ...
- bzoj 4004 [JLOI2015]装备购买 拟阵+线性基
[JLOI2015]装备购买 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1820 Solved: 547[Submit][Status][Dis ...
- 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\ ...
- 【HDU 3949】 XOR (线性基,高斯消元)
XOR Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- 高斯消元 & 线性基【学习笔记】
高斯消元 & 线性基 本来说不写了,但还是写点吧 [update 2017-02-18]现在发现真的有好多需要思考的地方,网上很多代码感觉都是错误的,虽然题目通过了 [update 2017- ...
随机推荐
- Oracle索引知识学习笔记
目录 一.Oracle索引简介 1.1 索引分类 1.2 索引数据结构 1.3 索引特性 1.4 索引使用注意要点 1.5.索引的缺点 1.6.索引失效 二.索引分类介绍 2.1.位图索引 1.2.函 ...
- 一个动态构建 LambdaExpression Tree 的示例
直接贴代码了: public class ExpressionTreeBuildingSampleTwo : Sample { public override string Name { get; } ...
- Oracle 原生驱动带来的精度问题的分析与解决
问题 Oracle 官方提供了 dotnet core 驱动,但我们在使用中遇到了精度问题. 复现 以下代码运行数学运算 1/3,无论是 OracleCommand.ExecuteScalar() 还 ...
- MySQL5.8下载及安装——免安装版
1.下载MySQL5.8下载地址:https://dev.mysql.com/downloads/mysql/ 图一: 图二: 2.如何安装.配置mysql-8.0.17-winx64.zip下载完成 ...
- yum 找不到程序,yum更换国内阿里源
使用百度云服务器,发现百度yum源非常不稳定,果断采用阿里源,操作步骤如下: 一.备份 $ cd /etc/yum.repos.d/ $ mv baidu-bcm.repo baidu-bcm.rep ...
- conda opencv cv2.imshow无法使用
error: -------src-dir-------/opencv-2.4.10/modules/highgui/src/window.cpp:501: error: (-2) The funct ...
- dubbo入门学习
官方网址:http://dubbo.apache.org/zh-cn/index.html 学习可以参考官网中文文档:http://dubbo.apache.org/zh-cn/docs/user/q ...
- Java学习——反射
Java学习——反射 摘要:本文主要讲述了什么是反射,使用反射有什么好处,以及如何使用反射. 部分内容来自以下博客: https://www.cnblogs.com/tech-bird/p/35253 ...
- SharpGL之Viewport
视口变换主是将视景体内投影的物体显示到二维的视口平面上. 在计算机图形学中,它的定义是将经过几何变换, 投影变换和裁剪变换后的物体显示于屏幕指定区域内. 前面我们讨论过的透视投影, 正射投影, 它们都 ...
- amanda安装
下载地址 http://www.amanda.org/download.php http://www.zmanda.com/download-amanda.php 编译安装 编译出错: error: ...