原文链接 https://www.cnblogs.com/cly-none/p/9813163.html

题意:给出初始序列\(a\)和目标序列\(b\),都有\(n\)个元素。每次操作可以把\(a\)中的一个元素替换为\(a\)中所有元素的异或和,问最少操作多少次,把序列\(a\)变成序列\(b\),或判断无解。

\(n \leq 10^5\)

首先,这个“替换为所有元素的异或和”,其实就是一开始有\(v\)为\(a\)中所有元素异或和,每次操作把\(a\)中某个元素与\(v\)交换。再转化一下,也就是一开始\(a_0\)为\(a\)中所有元素的异或和,每次可以把\(a\)中的某个元素和\(a_0\)交换。

这样很容易能判断无解的情况。现在只考虑如何求出操作的最小次数。

先不考虑元素相等的情况。那么就变成了一个排列的置换。考虑其中的每一个环,设环大小为\(m \, (m > 1)\),假如其中不包含\(a_0\),那么这个环就需要\(m+1\)次操作来处理;否则只需要\(m-1\)次。

而当有元素相等时,我们也可以类似于排列处理。定义每一对\((a_i,b_i)\)产生一条\((a_i,b_i)\)的有向边。因为包含\(a_0\)的环的个数是固定的,所以要最小化答案,我们就要最小化环的个数。但是这道题的图存在特殊性质:每一个弱连通分量都是由若干个有向环组成的,这意味着一定存在欧拉闭迹。因此,每个连通分量都能用只一个环解决。这显然也是答案的下界。

然后还有\(a_0\)的一点细节。

  • \(a_0 \neq b_0\)。那么,\(a_0\)一定在一个大于1的环上。最终答案减二。
  • \(a_0 = b_0\),但\(a_0\)所在的弱连通分量大于1。这样,那个弱连通分量的操作个数能少一个。
  • \(a_0 = b_0\),且\(a_0\)所在弱连通分量大小为1。那它对答案没有什么影响。

时间复杂度\(O(n \log n)\)。

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N],n,b[N],tmp,ans,cur,uni[N],sz[N],vis[N];
map<int,int> mp;
typedef pair<int,int> pii;
vector<int> vec;
template <typename tp>
void outputarr(tp *a,tp *b) {
while (a != b)
cerr << *a << ' ', ++ a;
cerr << endl;
}
int getfa(int pos) {
return pos == uni[pos] ? pos : uni[pos] = getfa(uni[pos]);
}
int main() {
scanf("%d",&n);
for (int i = 1 ; i <= n ; ++ i)
scanf("%d",&a[i]), tmp ^= a[i];
a[0] = tmp;
for (int i = 1 ; i <= n ; ++ i)
scanf("%d",&b[i]);
for (int i = 0 ; i <= n ; ++ i)
++ mp[a[i]];
for (int i = 1 ; i <= n ; ++ i) {
if (!mp.count(b[i]))
return puts("-1"), 0;
if (mp[b[i]] == 0) return puts("-1"), 0;
mp[b[i]]--;
}
for (int i = 0 ; i <= n ; ++ i)
if (mp[a[i]]) b[0] = a[i];
for (int i = 0 ; i <= n ; ++ i)
vec.push_back(a[i]);
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()),vec.end());
for (int i = 0 ; i <= n ; ++ i)
a[i] = lower_bound(vec.begin(),vec.end(),a[i]) - vec.begin() + 1, \
b[i] = lower_bound(vec.begin(),vec.end(),b[i]) - vec.begin() + 1;
for (int i = 0 ; i <= n ; ++ i)
uni[a[i]] = a[i];
for (int i = 0 ; i <= n ; ++ i) {
int x = getfa(a[i]), y = getfa(b[i]);
if (x != y)
uni[x] = y;
}
for (int i = 0 ; i <= n ; ++ i) {
if (a[i] == b[i]) continue;
++ ans;
++ sz[getfa(a[i])];
}
for (int i = 0 ; i <= n ; ++ i) {
if (a[i] == b[i]) continue;
if (a[i] == getfa(a[i]) && !vis[a[i]]) {
++ ans;
vis[a[i]] = 1;
}
}
if (a[0] != b[0]) ans --;
if (sz[getfa(a[0])] > 1) ans --;
printf("%d\n",ans);
return 0;
}

小结:早上的训练赛搬了这道题。从我的FST中,也可以看出我对问题的考虑不够仔细。补题过程中思维混乱的问题也很明显,导致花费了很多时间。

【做题】agc016d - XOR Replace——序列置换&环的更多相关文章

  1. AGC016D - XOR Replace 置换/轮换

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

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

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

  3. [agc016d]xor replace

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

  4. AtCoder Grand Contest 11~17 做题小记

    原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-11-to-20.html UPD(2018-11-16): ...

  5. CodeM美团点评编程大赛复赛 做题感悟&题解

    [T1] [简要题意]   长度为N的括号序列,随机确定括号的方向:对于一个已确定的序列,每次消除相邻的左右括号(右左不行),消除后可以进一步合并和消除直到不能消为止.求剩下的括号的期望.\(N \l ...

  6. bzoj5108: [CodePlus2017]可做题

    Description qmqmqm希望给sublinekelzrip出一道可做题.于是他想到了这么一道题目:给一个长度为n的非负整数序列ai,你需 要计算其异或前缀和bi,满足条件b1=a1,bi= ...

  7. SDOI2016 R1做题笔记

    SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...

  8. AtCoder Grand Contest 1~10 做题小记

    原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-1-to-10.html 考虑到博客内容较多,编辑不方便的情 ...

  9. bzoj5108 [CodePlus2017]可做题 位运算dp+离散

    [CodePlus2017]可做题 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 87  Solved: 63[Submit][Status][Dis ...

随机推荐

  1. java开学考试有感以及源码

    一.感想 Java开学测试有感 九月二十号,王老师给我们上的第一节java课,测试. 说实话,不能说是十分有自信,但还好,直到看见了开学测试的题目,之前因为已经做过了王老师发的16级的题目,所以当时还 ...

  2. loadrunner笔记(二):飞机订票系统--客户信息注册

    (一)  几个重要概念说明 集合点:同步虚拟用户,以便同一时间执行任务. 事务:事务是指服务器响应用户请求所用的时间,当然它可以衡量某个操作,如登录所需要的时间,也可以衡量一系列的操作所用的时间,如从 ...

  3. 教师信息管理系统(方式一:数据库为oracle数据库;方式二:存储在文件中)

    方式一: 运行截图 数据库的sql语句: /*Navicat Oracle Data TransferOracle Client Version : 12.1.0.2.0 Source Server ...

  4. js设计模式(五)---观察者模式

    概述: 观察者模式也叫 “ 发布-订阅 " 模式 , 发布者发布信息是不需要考虑订阅者是谁?添加订阅者的时候也不需要通知发布者. 应用: 最经典的就是: DOM事件 开发过程中我们常用自定义 ...

  5. HTML、CSS知识点,面试开发都会需要--No.7 数据列表

    No.7 数据列表 1.无序列表Unordered List 无序列表用block-level元素ul(unordered list)表示,每个item单独使用li(list)标记.如下代码所示: & ...

  6. 线程同步-使用ReaderWriterLockSlim类

    使用ReaderWriterLockSlim创建一个线程安全的机制,在多线程中对一个集合进行读写操作.ReaderWriterLockSlim代表了一个管理资源访问的锁,允许多个线程同时读取,以及独占 ...

  7. [No0000186]治愈系课程教材 第一课

    一部分:时态 时态有时间和特点组成 时间:现在.过去.将来 特点:一般.完成.进行.完成进行 所以时态总共有12种(加上过去将来的时间又多出4种时态,总共16种) 一般现在时 一般过去时 一般将来时 ...

  8. Web开发——HTML基础(HTML响应式Web设计 Bootstrap)

    参考: 参考:http://www.bootcss.com/ 目录: 1.什么是响应式 Web 设计? 2.创建自己的响应设计 3.使用 Bootstrap 1.什么是响应式 Web 设计? RWD ...

  9. Jmeter学习之-获取登录的oken值(2)

    此篇介绍获取登录token的第二种方式--json提取器提取 PS:此方法针对接口返回值为json串格式 在登录请求上右键添加JSON提取器                               ...

  10. 【JVM】-NO.110.JVM.1 -【GC垃圾收集器】

    Style:Mac Series:Java Since:2018-09-10 End:2018-09-10 Total Hours:1 Degree Of Diffculty:5 Degree Of ...