agc016D - XOR Replace(图论 智商)
题意
给出两个长度为\(n\)的数组\(a, b\)
每次可以将\(a\)中的某个数替换为所有数\(xor\)之和。
若\(a\)数组可以转换为\(b\)数组,输出最少操作次数
否则输出\(-1\)
Sol
一般那看到这种\(N \leqslant 10^5\)而且不可做的题肯定是先找结论啦
不难看出,我们把所有数\(xor\)起来的数替换掉之后再次\(xor\),得到的一定是被替换掉的数。
实际上,我们可以把xor出来的数放到一个新的位置\(N+1\),这样每次操作就变成了交换第\(N+1\)个位置的数和任意一个位置\(x\)的数
总的问题就变成了
给出两个长度为\(N+1\)的数组\(a, b\),每次可以在\(a\)中交换\(\forall i \in [1, n]\)位置和\(N+1\)位置的数,问最少交换几次变为\(b\)数组
首先把\(-1\)的情况判掉,很显然,把两个数组排序后,若存在一个位置不相同,则一定无解
否则一定有解。
到这里我就不会了。。。。
官方题解非常神仙。
对于\(i\)位置,若\(a_i \not = b_i\),则向\(a_i\)到\(b_i\)连一条边
最终答案 = 总边数 + 联通块数 - 1
想一想为什么,对于联通块内的点,假设其大小为\(x\),我们一定可以通过\(x-1\)次操作把他们对应的\(a\)和\(b\)变的相同
对于不同联通块之间,我们还需要一步操作使得第\(N+1\)个位置的数在两个联通块之间转化(第一个除外)
对于第\(N+1\)个位置需要单独考虑:如果它已经在联通块里则不需要考虑,否则把它看做单独联通块
否则
2
1 3
3 1
可以用并查集维护联通块个数
#include<bits/stdc++.h>
const int MAXN = 4e5 + 10;
using namespace std;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N;
int a[MAXN], b[MAXN], ta[MAXN], tb[MAXN], sa, sb, tot = 0, date[MAXN], fa[MAXN];
map<int, bool> ti;
int find(int x) {
return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}
int unionn(int x, int y) {
fa[x] = y;
}
int main() {
N = read();
for(int i = 1; i <= N; i++) a[i] = read(), sa ^= a[i]; a[N + 1] = sa;
for(int i = 1; i <= N; i++) b[i] = read(), sb ^= b[i]; b[N + 1] = sb;
N++;
memcpy(ta, a, sizeof(a)); memcpy(tb, b, sizeof(b));
sort(ta + 1, ta + N + 1); sort(tb + 1, tb + N + 1);
for(int i = 1; i <= N - 1; i++) if(ta[i] != tb[i]) return puts("-1"), 0;
int ans = 0, num = 0;
for(int i = 1; i <= N; i++)
if(a[i] != b[i] || (i == N)) {
date[++num] = a[i]; date[++num] = b[i];
if(i < N)ans++;//最后一块单独考虑
}
if(ans == 0) return puts("0"), 0;
sort(date + 1, date + num + 1);
num = unique(date + 1, date + num + 1) - date - 1;
for(int i = 1; i <= num; i++) fa[i] = i;
for(int i = 1; i <= N; i++)
if(a[i] != b[i]) {
a[i] = lower_bound(date + 1, date + num + 1, a[i]) - date,
b[i] = lower_bound(date + 1, date + num + 1, b[i]) - date;
if(!ti[a[i]]) ti[a[i]] = 1;
if(!ti[b[i]]) ti[b[i]] = 1;
unionn(find(a[i]), find(b[i]));
}
for(int i = 1; i <= num; i++)
if(fa[i] == i) ans++;
printf("%d", ans - 1);
return 0;
}
agc016D - XOR Replace(图论 智商)的更多相关文章
- AGC016D - XOR Replace 置换/轮换
目录 题目链接 题解 代码 题目链接 AGC016D - XOR Replace 题解 可以发现一次操作相当于一次置换 对于每个a上的位置映射到b对应 可以找到置换群中的 所有轮换 一个k个元素的轮换 ...
- 【做题】agc016d - XOR Replace——序列置换&环
原文链接 https://www.cnblogs.com/cly-none/p/9813163.html 题意:给出初始序列\(a\)和目标序列\(b\),都有\(n\)个元素.每次操作可以把\(a\ ...
- [agc016d]xor replace
题意: 题解: 棒棒的神仙题...这题只是D题???(myh:看题五分钟,讨论两小时) 首先这个异或和是假的,比如我现在有$a=(a_1,a_2,a_3,a_4)$,操作一下$a_2$,就变成了$a= ...
- AGC 16 D - XOR Replace
AGC 16 D - XOR Replace 附上attack(自为风月马前卒爷) 的题解 Problem Statement There is a sequence of length N: a=( ...
- 【agc016D】XOR Replace
Portal --> agc016D Description 一个序列,一次操作将某个位置变成整个序列的异或和,现在给定一个目标序列,问最少几步可以得到目标序列 Solution 翀 ...
- AtcoderGrandContest 016 D.XOR Replace
$ >AtcoderGrandContest \space 016 D.XOR\space Replace<$ 题目大意 : 有两个长度为 \(n\) 的数组 \(A, B\) ,每次操作 ...
- TTTTTTTTTTTTTTTTTTT CF 银行转账 图论 智商题
C. Money Transfers time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Agc016_D XOR Replace
传送门 题目大意 给定两个长为$n$的序列$A,B$你可以进行若干组操作,每次操作选定一各位置$x$,令$A_x$等于$A$的异或和. 问能否通过一定操作使得$A$成为$B$,如果能,求最小操作书数. ...
- Atcoder D - XOR Replace(思维)
题目链接:http://agc016.contest.atcoder.jp/tasks/agc016_d 题解:稍微想一下就知道除了第一次的x是所有的异或值,之后的x都是原先被替换掉的a[i]所以要想 ...
随机推荐
- [zhuan]VMware中bridge方式网络不能上网的解决办法
http://jingpin.jikexueyuan.com/article/31601.html 安装好VMware 7后,打开原来的虚拟机文件,发现不能上网,原来的Ethernet是设置的Brid ...
- Bazinga 字符串HASH 这题不能裸HASH 要优化 毒瘤题
Ladies and gentlemen, please sit up straight. Don't tilt your head. I'm serious. For nn given string ...
- java重写equals和hashCode方法
一.重写equals方法 如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等. 利用equals比较八大包装对象(如int,f ...
- 题解【poj2774 Long Long Message】
Description 求两个串的最长连续公共字串 Solution 后缀数组入门题吧 把两个串连在一起,中间加一个分隔符,然后跑一遍后缀数组,得到 height 和 sa 一个 height[i] ...
- HDU1832 二维线段树求最值(模板)
Luck and Love Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- 【Android】完善Android学习(二:API 2.3.4)
备注:之前Android入门学习的书籍使用的是杨丰盛的<Android应用开发揭秘>,这本书是基于Android 2.2API的,目前Android已经到4.4了,更新了很多的API,也增 ...
- C11简洁之道:模板改进
1. 右尖括号 我们在C++98/03中使用泛型编程的时候,经常遇到“>>”被当作右移操作符,而不是模板参数的结尾.假如我们有如下代码: template <typename T& ...
- Linux下Tomcat重启脚本
我们重启Tomcat服务的时候,Tomcat自带的shutdown.sh脚本有时并不能真正杀死进程,经常需要我们用“kill -9 pid”的方式来杀死进程. 下面的脚本可以简化我们的操作,执行可杀死 ...
- 【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)
题目链接 容易发现\(a,b,c\)肯定是在一条直链上的. 定义\(size(u)\)表示以\(u\)为根的子树大小(不包括\(u\)) 分两种情况, 1.\(b\)是\(a\)的祖先,对答案的贡献是 ...
- centos7.2进入单用户模式修改密码
1 - 在启动grub菜单,选择编辑选项启动 2 - 按键盘e键,来进入编辑界面 3 - 找到Linux 16的那一行,将ro改为rw init=/sysroot/bin/sh 4 - 现在按下 Co ...