$ >AtcoderGrandContest \space\ 016\ D.XOR\space Replace<$

题目大意 :

有两个长度为 \(n\) 的数组 \(A, B\) ,每次操作将 \(A\) 中的一个元素替换为 \(A\) 中所有元素的异或和,求最少几次操作可以从 \(A\) 变换到 \(B\) 。

\(1 \leq n \leq 10^5\)

解题思路 :

设初始状态的异或和为 \(S\) ,第一次替换掉的数为 \(x\) ,容易发现新的数列的异或和为 \(x\) ,可以简单证明每一次的异或和等于上一次被替换的数。

那么问题就转化为对于一个序列 \(A\) ,\(A_{n+1} = S\) ,第一次取出 \(S\) ,之后每一次替换掉某个数并取出它来替换别人,事实上每一个取出的数都会被放到其在 \(B\) 中的位置上。

此时 \(A\) 数组就构成了若干个置换,最小花费就是置换的数量加上环上的点数 \(-1\) ,但是一个数可能会有多个合法的位置可以选,直接构造的话置换的数量可能不会优。

但是观察发现如果两个置换存在数值相等的位置,那么可以通过交换 \(next\) 指针变成一个置换,所以只需要按照数值来合并联通块就能求出置换的最小数量,可以用并查集来维护。

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 1000005;
map<int, int> id;
int fa[N], s1[N], s2[N], a[N], b[N], n, col, ans;
inline int ask(int x){ return x == fa[x] ? x : fa[x] = ask(fa[x]); }
inline void merge(int x, int y){
int p = ask(x), q = ask(y); if(p != q) fa[p] = q;
}
signed main(){
read(n);
for(int i = 1; i <= n; i++) read(a[i]), a[n+1] ^= a[i];
for(int i = 1; i <= n; i++) read(b[i]), b[n+1] ^= b[i];
for(int i = 1; i <= n + 1; i++) s1[i] = a[i], s2[i] = b[i];
sort(s1 + 1, s1 + n + 2), sort(s2 + 1, s2 + n + 2);
for(int i = 1; i <= n + 1; i++) if(s1[i] != s2[i]) return puts("-1"), 0;
for(int i = 1; i <= n; i++) if(a[i] != b[i]) ans++;
for(int i = 1; i <= n + 1; i++) fa[i] = i;
for(int i = 1; i <= n + 1; i++) if(a[i] != b[i]){
if(!id[a[i]]) id[a[i]] = ++col;
if(!id[b[i]]) id[b[i]] = ++col;
merge(id[a[i]], id[b[i]]);
}
if(!id[a[n+1]]) id[a[n+1]] = ++col;
if(!id[b[n+1]]) id[b[n+1]] = ++col;
for(int i = 1; i <= col; i++) if(fa[i] == i) ans++;
cout << ans - 1;
return 0;
}

AtcoderGrandContest 016 D.XOR Replace的更多相关文章

  1. AGC016D - XOR Replace 置换/轮换

    目录 题目链接 题解 代码 题目链接 AGC016D - XOR Replace 题解 可以发现一次操作相当于一次置换 对于每个a上的位置映射到b对应 可以找到置换群中的 所有轮换 一个k个元素的轮换 ...

  2. AGC 16 D - XOR Replace

    AGC 16 D - XOR Replace 附上attack(自为风月马前卒爷) 的题解 Problem Statement There is a sequence of length N: a=( ...

  3. agc016D - XOR Replace(图论 智商)

    题意 题目链接 给出两个长度为\(n\)的数组\(a, b\) 每次可以将\(a\)中的某个数替换为所有数\(xor\)之和. 若\(a\)数组可以转换为\(b\)数组,输出最少操作次数 否则输出\( ...

  4. 【做题】agc016d - XOR Replace——序列置换&环

    原文链接 https://www.cnblogs.com/cly-none/p/9813163.html 题意:给出初始序列\(a\)和目标序列\(b\),都有\(n\)个元素.每次操作可以把\(a\ ...

  5. 【agc016D】XOR Replace

    Portal --> agc016D Description ​ 一个序列,一次操作将某个位置变成整个序列的异或和,现在给定一个目标序列,问最少几步可以得到目标序列 ​ Solution ​ 翀 ...

  6. Agc016_D XOR Replace

    传送门 题目大意 给定两个长为$n$的序列$A,B$你可以进行若干组操作,每次操作选定一各位置$x$,令$A_x$等于$A$的异或和. 问能否通过一定操作使得$A$成为$B$,如果能,求最小操作书数. ...

  7. [agc016d]xor replace

    题意: 题解: 棒棒的神仙题...这题只是D题???(myh:看题五分钟,讨论两小时) 首先这个异或和是假的,比如我现在有$a=(a_1,a_2,a_3,a_4)$,操作一下$a_2$,就变成了$a= ...

  8. Atcoder D - XOR Replace(思维)

    题目链接:http://agc016.contest.atcoder.jp/tasks/agc016_d 题解:稍微想一下就知道除了第一次的x是所有的异或值,之后的x都是原先被替换掉的a[i]所以要想 ...

  9. 【AtCoder】AGC016

    A - Shrinking 用每个字母模拟一下就行 #include <bits/stdc++.h> #define fi first #define se second #define ...

随机推荐

  1. 【BZOJ】1875: [SDOI2009]HH去散步 矩阵快速幂

    [题意]给定n个点m边的无向图,求A到B恰好经过t条边的路径数,路径须满足每条边都和前一条边不同.n<=20,m<=60,t<=2^30. [算法]矩阵快速幂 [题解]将图的邻接矩阵 ...

  2. eclipse运行Android项目出现“The connection to adb is down, and a severe error has occured. You must restart adb and Eclipse. ”

    重启eclipse之后仍然出现同样错误,此时可以尝试一下方法: cmd打开命令窗口: 之后重启eclipse,基本可以解决问题!

  3. ansible 下lineinfile详细使用 【转】

    转自 ansible 下lineinfile详细使用 - 散人 - 51CTO技术博客http://zouqingyun.blog.51cto.com/782246/1882367 一.简述 这几天在 ...

  4. loadrunner 测试问题汇总

    1.关于Error -27791: Error -27790:Error -27740:        错误如下:        Action.c(198): Error -27791: Server ...

  5. Builder设计模式--改善构造器多个参数时可显著改善可读性

    作为一名程序开发者,设计模式其实一直有在接触,只是没有专门的去学过,所以可能对设计模式没有一个系统的理解.在一次项目中,需要使用到第三方服务商提供的功能,为了尽快的熟悉其功能代码,在官网下了demo来 ...

  6. redis局域网内开启访问

    若需要开启A(192.168.0.3)的访问1.配置confg bind 192.168.0.3 2.设置访问密码 requirepass password 3.重新载入配置 ./redis-serv ...

  7. leetcode 之Sum系列(七)

    第一题是Two Sum 同样是用哈希表来做,需要注意的是在查打gap是要排除本身.比如target为4,有一个值为2,gap同样为2. vector<int> twoSum(vector& ...

  8. js中的for循环

    预定义: var arr=[22,33,12,34];//数组(特殊的对象) var obj={ //对象 name:"Jack", age:"99", sex ...

  9. thinkphp5 返回数组提示variable type error: array

    浏览器访问控制器函数,而函数返回的是数组: function timeArr(){ $time = array(); for($i=1;$i<=7;$i++){ $d= date('d',Tim ...

  10. day3修改配置文件

    有如下配置文件,在指定文件位置添加一条新的记录: global log 127.0.0.1 local2 daemon maxconn log 127.0.0.1 local2 info defaul ...