(与题目中下标不同,这里令下标为$[0,2^{k})$来方便运算)

根据异或的性质,显然有解的必要条件是$\bigoplus_{i=0}^{2^{k}-1}a_{i}=0$

在此基础上,我们考虑构造——

定义$solve(i,j,x)$表示在当前$p_{i}$和$q_{i}$的基础上,构造$p'_{i}$与$q'_{i}$,使得:

1.$\forall 0\le t<2^{k}且t\ne i且t\ne j,p_{t}\oplus q_{t}=p'_{t}\oplus q'_{t}$

2.$p_{i}\oplus q_{i}=p'_{i}\oplus q'_{i}\oplus x$,$p_{j}\oplus q_{j}=p'_{j}\oplus q'_{j}\oplus x$

初始令$\forall 0\le i<2^{k},p_{i}=q_{i}=i$,接下来只需要不断执行$solve(i,i+1,\bigoplus_{j=0}^{i}a_{j})$即可

考虑如何执行$solve(i,j,x)$这个操作,首先若$x=0$直接退出,否则继续分析:

由于都是排列,构造可以通过交换来实现,更具体的来说,我们希望找到$t$,使得$p_{i}$与$p_{t}$交换、$q_{j}$与$q_{t}$交换,使得满足$p_{i}\oplus q_{i}=p'_{i}\oplus q'_{i}\oplus x$(不关心$j$以及其他位置)

上述要求即$p_{t}=p_{i}\oplus x$,根据排列总是存在,然后执行这些交换,对之后的情况分类讨论:

1.$t=j$,那么即已经合法(根据$x\ne 0$,必然有$t\ne i$)

2.$t\ne j$,不难发现交换后不合法的位置仅有$t$和$j$,且我们希望将其异或值异或上$q_{t}\oplus q_{j}\oplus x$,不难发现这就是要求执行$solve(t,j,q_{t}\oplus q_{j}\oplus x)$

重复执行上述递归过程,注意到$j$是不变的,只需要证明$i$不会重复经过一个位置,那么递归次数就是$o(2^{k})$(找到$p_{t}$可以预处理做到$o(1)$),总复杂度即$o(2^{2k})$

下面,我们就要来证明$i$不能重复:

反证法,即假设存在重复,不妨假设是与第一次操作相同(可以将之前与其相同的操作看作第一次),即假设这些递归的$i$依次为$I_{1},I_{2},...,I_{m+1}$,其中$\forall 1\le i<j\le m,I_{i}\ne I_{j}$且$I_{m+1}=I_{1}$

假设递归$I_{1}$时是$solve(I_{1},j,x)$,归纳可得递归$I_{i}$时是$solve(I_{i},j,x\oplus q_{j}\oplus q_{I_{i}})$,接下来考虑递归$I_{m}$时整个序列在递归$I_{1}$前的变化——
$$
\begin{pmatrix}I_{1}&I_{2}&I_{3}&...&I_{m-1}&I_{m}&j\\p_{I_{2}}&p_{I_{3}}&p_{I_{4}}&...&p_{I_{m}}&p_{I_{1}}&p_{j}\\q_{I_{1}}&q_{j}&q_{I_{2}}&...&q_{I_{m-2}}&q_{I_{m-1}}&q_{I_{m}}\end{pmatrix}
$$
(其中第一行为下标,第2行和第3行描述当前的$p$和$q$,这里的$p_{i}$和$q_{i}$都是$I_{1}$操作之前$i$位置的值)

由于是$solve(I_{m},j,x\oplus q_{j}\oplus q_{I_{m}})$,同时由于$I_{m+1}=I_{1}$,即$p_{I_{2}}=p_{I_{1}}\oplus x\oplus q_{j}\oplus q_{I_{m}}$

同时,根据$I_{1}$第1次找到$I_{2}$,有$p_{I_{2}}=p_{I_{1}}\oplus x$,代入后不难得到$q_{j}=q_{I_{m}}$,由于是排列,即$I_{m}=j$,即矛盾

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 5005
4 int n,k,a[N],p[N],q[N],pos[N];
5 void solve(int i,int j,int x){
6 if (!x)return;
7 int t=pos[(p[i]^x)];
8 swap(p[i],p[t]);
9 swap(pos[p[i]],pos[p[t]]);
10 swap(q[j],q[t]);
11 if (t!=j)solve(t,j,(q[t]^q[j]^x));
12 }
13 int main(){
14 scanf("%d",&k);
15 n=(1<<k);
16 for(int i=0;i<n;i++){
17 scanf("%d",&a[i]);
18 if (i)a[i]^=a[i-1];
19 p[i]=q[i]=pos[i]=i;
20 }
21 if (a[n-1]){
22 printf("Fou");
23 return 0;
24 }
25 for(int i=0;i<n;i++)solve(i,i+1,a[i]);
26 printf("Shi\n");
27 for(int i=0;i<n;i++)printf("%d ",p[i]);
28 printf("\n");
29 for(int i=0;i<n;i++)printf("%d ",q[i]);
30 }

[cf1168E]Xor Permutations的更多相关文章

  1. Codeforces Round #440 (Div. 2, based on Technocup 2018 Elimination Round 2) D. Something with XOR Queries

    地址:http://codeforces.com/contest/872/problem/D 题目: D. Something with XOR Queries time limit per test ...

  2. Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  3. [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...

  4. [LeetCode] Permutations II 全排列之二

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  5. [LeetCode] Permutations 全排列

    Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the follow ...

  6. 二分+DP+Trie HDOJ 5715 XOR 游戏

    题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  7. POJ2369 Permutations(置换的周期)

    链接:http://poj.org/problem?id=2369 Permutations Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  8. BZOJ 2115 【Wc2011】 Xor

    Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...

  9. Permutations

    Permutations Given a collection of distinct numbers, return all possible permutations. For example,[ ...

随机推荐

  1. JUC之Executor,ExecutorService接口,AbstractExecutorService类

    java多线程的Executor中定义了一个execut方法,ExecutorService接口继承了Executor接口,并进行了功能的扩展组合,定义了shutdown,shutdownNow,su ...

  2. pip安装加速

    PIP国内镜像源 名称 源地址 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/s ...

  3. Android系统编程入门系列之应用间数据共享ContentProvider

    内容提供者ContentProvider与前文的界面Activity.服务Service.广播接收者BroadcastReveiver,并列称为Android的四大组件,均是需要自定义子类继承上述组件 ...

  4. 2021.7.27--Benelux Algorithm Programming Contest 2020 补提

    I Jigsaw 题目内容: 链接:https://ac.nowcoder.com/acm/contest/18454/I 来源:牛客网 You have found an old jigsaw pu ...

  5. 听说,99% 的 Go 程序员都被 defer 坑过

    原文链接: 听说,99% 的 Go 程序员都被 defer 坑过 先声明:我被坑过. 之前写 Go 专栏时,写过一篇文章:Go 专栏|错误处理:defer,panic 和 recover.有小伙伴留言 ...

  6. Golang通脉之map

    Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现. map 是一种无序的键值对的集合.map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值 map ...

  7. jenkins的安装、配置使用

    1.jenkins的使用 (1).需要先下载安装JDK 配置jdk的环境 变量JAVA_HOME的值是 jdk 的安装位置, 然后下载安装tomcat 安装好了之后,打开tomcat下的bin文件夹, ...

  8. Windows内核开发-10-监听对象

    Windows内核开发-10-监听对象 Windows内核除了可以监听进程,线程.dll还可以监听特定的对象和注册表.这里先讲一下监听对象. 监听对象 内核提供了一种可以监听对特定的对象类型的句柄进行 ...

  9. 如何理解Stand SPI Dual SPI 和Quad SPI??

    1.首先看一下接口 Standard SPI: CLK, /CS, DI, DO, /WP, /Hold Dual SPI: CLK, /CS, IO0, IO1, /WP, /Hold Quad S ...

  10. 转:SYNOPSYS VCS Makefile文件编写与研究

    SYNOPSYS VCS Makefile文件编写与研究 这个Makefile是synopsys提供的模板,看上去非常好用,你只要按部就班提供实际项目的参数就可以了.我们来看这个文件的头部说明:mak ...