原题链接
https://agc016.contest.atcoder.jp/tasks/agc016_d
Description
给出一个n个数的序列a,每次操作可以将一个数变成整个序列的值的异或
求最少需要多少次才能将a变成目标序列b
无法完成输出-1
n<=100000
Solution
考虑操作的本质
只要按位稍微分析一下,就可以发现,题目相当于一开始手里抓着整个序列a的异或,一次操作可以将手上的数与序列中的某个数换过来
知道操作的本质就简单许多
如果能够完成,方便起见将a的异或和b的异或分别加到序列末,排序后两个序列显然完全相同
这样就把-1判掉了
只有a[i]!=b[i]的位置我们是需要调整的
那么将a,b离散化,a[i]与b[i]连边
将一个联通块内操作所需要的次数就是联通块大小
而联通块之间跳需要1的代价
此时由于我们一开始手上抓着的是a的异或和
如果它刚好在某一个联通块里面就不用考虑了,否则就必须将它自己看做一个大小为0的联通块
最后-1是在联通块之间跳的次数是联通块个数-1
联通块可以用并查集维护,离散化我实在懒惰了用了map
Code