题目链接


\(Description\)

给定两个长为\(n\)的数组\(x_i,y_i\)。每次你可以选定\(i,j\),令\(x_i=x_i\ \mathbb{xor}\ x_j\)(\(i,j\)可以相等)。要求若干次操作后使得\(x\)变成\(y\),输出方案。操作次数不能多于\(10^6\),无解输出\(-1\)。

\(n\leq10^4,\ 0\leq x_i,y_i\leq10^9\)。

\(Solution\)

考虑异或的两个基本性质:

  1. 异或是可逆的,逆运算就是它本身。
  2. 可以交换两个数:a^=b,b^=a,a^=b

考虑线性基。构造出\(x\)的线性基,如果\(y\)中存在元素不能被\(x\)表示出来,那么无解。

我们发现对于不在线性基中的元素\(x_i\),得到\(y_i\)是很容易的,只需要求一下在线性基中\(\mathbb{xor}\)出\(y_i\)需要异或哪些数。

对于在线性基中的元素,设有\(t\)个,它们之间不是很好做。把\(t\)个\(x_i\)对应的\(y_i\)需要\(\mathbb{xor}\)哪些基写成一个\(t\)位二进制数。由第二个性质,我们可以高斯消元将这个\(t\times t\)的矩阵消成一个上三角矩阵,这样从高位到低位做不同基之间就互不影响了,我们可以\(\mathbb{xor}\)出这个矩阵。

而由第一个性质,将高斯消元的过程反过来操作这个上三角矩阵,就可以还原回\(y\)数组。


//46ms	3100KB
#include <cstdio>
#include <cctype>
#include <vector>
#include <algorithm>
#define BIT 29
#define mp std::make_pair
#define pr std::pair<int,int>
#define gc() getchar()
typedef long long LL;
const int N=10005,M=BIT+2; int x[N],y[N],base[M],is_base[N],b[M],sx[M],sy[N];
std::vector<pr> ans,opt; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
} int main()
{
int n=read();
for(int i=1; i<=n; ++i) x[i]=read();
for(int i=1; i<=n; ++i) y[i]=read();
for(int i=1; i<=n; ++i)
{
is_base[i]=-1;
for(int j=BIT,s=0; ~j; --j)
if(x[i]>>j&1)
if(base[j]) x[i]^=x[base[j]], s^=sx[j];
else
{
is_base[i]=j, base[j]=i, sx[j]=s|(1<<j);
break;
}
}
int cnt=0;
for(int i=1; i<=n; ++i)
{
int s=0;
for(int j=BIT; ~j; --j)
if(y[i]>>j&1)
if(base[j]) y[i]^=x[base[j]], s^=sx[j];
else return puts("-1"),0;
if(~is_base[i]) {b[cnt]=i, sy[cnt++]=s; continue;}//可以等于0啊。。
ans.push_back(mp(i,i));
for(int j=BIT; ~j; --j) if(s>>j&1) ans.push_back(mp(i,base[j]));
}
for(int i=0; i<cnt; ++i)
{
int s=sy[i]; sy[i]=0;
for(int j=0; j<cnt; ++j) if(s>>is_base[b[j]]&1) sy[i]|=1<<j;
}
for(int i=0; i<cnt; ++i)
{
if(!(sy[i]>>i&1))
for(int j=i+1; j<cnt; ++j)
if(sy[j]>>i&1)
{
opt.push_back(mp(b[i],b[j]));
opt.push_back(mp(b[j],b[i]));
opt.push_back(mp(b[i],b[j]));
std::swap(sy[i],sy[j]);
break;
}
if(sy[i]>>i&1)
for(int j=i+1; j<cnt; ++j)
if(sy[j]>>i&1)
opt.push_back(mp(b[j],b[i])), sy[j]^=sy[i];
}
for(int i=0; i<cnt; ++i)
{
if(!(sy[i]>>i&1)) ans.push_back(mp(b[i],b[i]));
for(int j=i+1; j<cnt; ++j)
if(sy[i]>>j&1) ans.push_back(mp(b[i],b[j]));
}
std::reverse(opt.begin(),opt.end());
for(auto v:opt) ans.push_back(v);
printf("%d\n",ans.size());
for(auto v:ans) printf("%d %d\n",v.first,v.second); return 0;
}

Codeforces.472F.Design Tutorial: Change the Goal(构造 线性基 高斯消元)的更多相关文章

  1. Educational Codeforces Round 63 (Rated for Div. 2) E 带模高斯消元

    https://codeforces.com/contest/1155/problem/E 题意 \(f(x)=a_0+a_1x+a_2x^2+...+a_kx^k,k \leq 10,0 \leq ...

  2. Codeforces Gym10008E Harmonious Matrices(高斯消元)

    [题目链接] http://codeforces.com/gym/100008/ [题目大意] 给出 一个n*m的矩阵,要求用0和1填满,使得每个位置和周围四格相加为偶数,要求1的数目尽量多. [题解 ...

  3. Codeforces 832E Vasya and Shifts - 高斯消元

    题目传送门 快速的传送门I 快速的传送门II 题目大意 (题意比较复杂,请自行阅读原题) 可以将原题的字母都看成它们的在字符表中的下标,这样问题就变成给定$n$个$m$维向量$\vec{a_{1}}, ...

  4. Codeforces Round #114 (Div. 1) E. Wizards and Bets 高斯消元

    E. Wizards and Bets 题目连接: http://www.codeforces.com/contest/167/problem/E Description In some countr ...

  5. CodeForces 24D Broken robot(期望+高斯消元)

    CodeForces 24D Broken robot 大致题意:你有一个n行m列的矩形板,有一个机器人在开始在第i行第j列,它每一步会随机从可以选择的方案里任选一个(向下走一格,向左走一格,向右走一 ...

  6. Codeforces 1163E 高斯消元 + dfs

    题意:给你一个集合,让你构造一个长度尽量长的排列,使得排列中任意相邻两个位置的数XOR后是集合中的数. 思路:我们考虑枚举i, 然后判断集合中所有小于1 << i的数是否可以构成一组异或空 ...

  7. Broken robot CodeForces - 24D (三对角矩阵简化高斯消元+概率dp)

    题意: 有一个N行M列的矩阵,机器人最初位于第i行和第j列.然后,机器人可以在每一步都转到另一个单元.目的是转到最底部(第N个)行.机器人可以停留在当前单元格处,向左移动,向右移动或移动到当前位置下方 ...

  8. Codeforces 446D - DZY Loves Games(高斯消元+期望 DP+矩阵快速幂)

    Codeforces 题目传送门 & 洛谷题目传送门 神仙题,%%% 首先考虑所有格子都是陷阱格的情况,那显然就是一个矩阵快速幂,具体来说,设 \(f_{i,j}\) 表示走了 \(i\) 步 ...

  9. Educational Codeforces Round 58 (Rated for Div. 2) G 线性基

    https://codeforces.com/contest/1101/problem/G 题意 一个有n个数字的数组a[],将区间分成尽可能多段,使得段之间的相互组合异或和不等于零 题解 根据线性基 ...

随机推荐

  1. web.xml中的ContextLoaderListener和DispatcherServlet区别

    ContextLoaderListener和DispatcherServlet都会在Web容器启动的时候加载一下bean配置. 区别在于: DispatcherServlet一般会加载MVC相关的be ...

  2. Spring Boot的Listener机制的用法和实现原理详解

    之前在介绍了在spring-boot启动过程中调用runner的原理,今天我们介绍另外一种可以实现相似功能的机制:spring-boot的Listener机制. 通过注册Listener,可以实现对于 ...

  3. js 打开摄像头方法 (定制摄像头)

    var video = document.getElementById("video");if (navigator.mediaDevices && navigat ...

  4. 20165206 2017-2018-2 《Java程序设计》第6周学习总结

    20165206 2017-2018-2 <Java程序设计>第6周学习总结 教材学习内容总结 String类:可以被直接使用,不可以有子类. String对象:可以使用String类声明 ...

  5. K/3 Cloud Web API接口说明文

    K/3 Cloud Web API接口说明文 目的 三方集成,提供第三方系统与Cloud集成调用接口. 技术实现 HTTP + Json 提供标准接口 编号 名称 说明 1 Kingdee.BOS.W ...

  6. python虚拟环境搭建

    1.安装python环境 2.检查pip 3.pip install virtualenv 4.创建测试:virtualenv  testvir 5.pip install virtualenvwra ...

  7. 一脸懵逼学习Hadoop中的序列化机制——流量求和统计MapReduce的程序开发案例——流量求和统计排序

    一:序列化概念 序列化(Serialization)是指把结构化对象转化为字节流.反序列化(Deserialization)是序列化的逆过程.即把字节流转回结构化对象.Java序列化(java.io. ...

  8. Vue报错:Uncaught TypeError: Cannot assign to read only property’exports‘ of object’#<Object>‘的解决方法

    发现问题 运行一下以前的一个Vue+webpack的 vue仿新闻网站  小项目,报错 由于自己vue学习不深入,老是这个报错,找了好久(确切的说是整整一下午^...^)才找到原因 -v- Uncau ...

  9. npm报错没有权限

    在npm install经常会报错没有权限 这个时候需要清除一下缓存 npm cache clean --force

  10. java中String和StringBuffer的区别

    前言 String和StringBuffer本质上都是修饰字符串的只是含义不同 StringBuffer叫做字符串缓冲区 首先看下string类的例子 public class Work1 { pub ...