(与题目中下标不同,这里令下标为$[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. 解决VSCODE"因为在此系统上禁止运行脚本"报错

    在VSCODE中使用yarn,结果报错: 找了下原因,是因为PowerShell执行策略的问题. 解决方法:   以管理员身份运行vscode;  执行:get-ExecutionPolicy,显示R ...

  2. 题解 「CTSC2018暴力写挂」

    题目传送门 题目大意 给出两个大小为 \(n\) 的树,求出: \[\max\{\text{depth}(x)+\text{depth}(y)-\text{depth}(\text{LCA}(x,y) ...

  3. spoj2 prime1 (区间筛)

    给定t组询问,每组询问包括一个l和r,要求\([l,r]\)的素数有哪些 其中\(t \le 10,1 \le l \le r \le 1000000000 , r-l \le 100000\) Qw ...

  4. DRF的action装饰器

    1.action装饰器 Django默认的路由分发规则决定了视图函数只能以get.post等请求方式命名,如果想要使用自定义的方式命名,我们可以使用action去映射请求方法名与自定义方法 view. ...

  5. 图解java 多线程模式 读书笔记

    第1章"Single Threaded Execution模式--能通过这座桥的只有一个人" 该模式可以确保执行处理的线程只能是一个,这样就可以有效防止实例不一致. 第⒉章&quo ...

  6. find+xargs+sed批量替换

    写代码时经常遇到要把 .c  和 .h的文件中的某些内容全部替换的情况,用sourceinsight 进行全局的查找是一个方法,但是sourceinsight只能替换一个文件中的字符串,不能同时替换多 ...

  7. Succeed_School

    # Author kevin_hou class School(object): def __init__(self,name,addr): self.name = name self.addr = ...

  8. [Beta]the Agiles Scrum Meeting 7

    会议时间:2020.5.21 20:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 issue yjy 暂无 tq 新增功能:添加.选择.展示多个评测机,对新增功能进行测试 评测部分增加 ...

  9. 利用Ambari平台安装与部署Hadoop

    * 本篇是利用Ambari平台安装与部署Hadoop,如果需要原生部署Hadoop,请点击以下地址: https://www.cnblogs.com/live41/p/15467263.html 一. ...

  10. 小白自制Linux开发板 十. NES游戏玩起来

    本篇基于我们制作的Debian文件系统而展开,而且我们这会玩一些高级的操作方式--用我们的小电脑进行程序编译.   所以本篇操作全部都在我们个的开发板上完成.   1. 开发环境搭建 首先安装gcc, ...