AtCoder Grand Contest 016 D - XOR Replace
2018-02-28 21:10
489 查看
Time limit : 2sec / Memory limit : 256MB
Score : 1000 points
Problem Statement
There is a sequence of length N: a=(a1,a2,…,aN). Here, each ai is a non-negative integer.Snuke can repeatedly perform the following operation:
Let the XOR of all the elements in a be x. Select an integer i (1≤i≤N) and replace ai with x.
Snuke’s objective is to match a with another sequence b=(b1,b2,…,bN). Here, each bi is a non-negative integer.
Determine whether the objective is achievable, and find the minimum necessary number of operations if the answer is positive.
Constraints
2≤N≤105ai and bi are integers.
0≤ai,bi<230
Input
Input is given from Standard Input in the following format:N
a1 a2 … aN
b1 b2 … bN
Output
If the objective is achievable, print the minimum necessary number of operations. Otherwise, print -1 instead.Sample Input 1
30 1 2
3 1 0
Sample Output 1
2At first, the XOR of all the elements of a is 3. If we replace a1 with 3, a becomes (3,1,2).
Now, the XOR of all the elements of a is 0. If we replace a3 with 0, a becomes (3,1,0), which matches b.
Sample Input 2
Copy3
0 1 2
0 1 2
Sample Output 2
0Sample Input 3
21 1
0 0
Sample Output 3
-1Sample Input 4
40 1 2 3
1 0 3 2
Sample Output 4
5Gist
给你两个序列 a 和序列 b ,长度各为 N 。要求最少的变换操作数,使得将序列 a 变为序列 b 。
操作:令 x=序列 a 每个元素的异或和,并用 x 代替一个 ai 。
数据范围:2≤N≤105 , 0≤ai,bi<230
Solution
要会做这题,就必须发现其操作的本质。发现除了第一次求异或和产生的数是新数外,之后的数都是旧的(替换的)。
因为替换后的异或和就是被替换的数本身(异或的性质)。
那么为了方便处理,就将第一次的新数放到那 N 个数的末尾,
操作就相当于将最后一个数与前面 N 个数中的某个数交换。
不合法的情况就是将两列数排序后不完全相同(无论如何都不能换到相同)。
之后某个位置上 a 要换成 b ,就 a 向b 连一条边,
每个连通块就需要 Size+1 次交换操作(除非包含第 N+1 个数,可以少一次,即答案减一)。
用一个并查集维护即可,注意存数判断时要用 Hash 表。
时间复杂度 O(N log N) 。
Code
#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> using namespace std; const int N=1e5+5,M=N*100+7; int tot,ans; int a ,b ,a1 ,b1 ; int f ,bel[M],h[M]; inline int read() { int X=0,w=0; char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } inline int get(int x) { return f[x]==x?x:f[x]=get(f[x]); } inline int hash(int x) { int y=x%M; while(h[y]>=0 && h[y]!=x) y=(y+1)%M; return y; } int main() { int n=read(); for(int i=1;i<=n;i++) { a[i]=a1[i]=read(); a[n+1]^=a[i]; } a1[n+1]=a[n+1]; for(int i=1;i<=n;i++) { b[i]=b1[i]=read(); b[n+1]^=b[i]; } b1[n+1]=b[n+1],n++; sort(a1+1,a1+1+n); sort(b1+1,b1+1+n); for(int i=1;i<=n;i++) if(a1[i]^b1[i]) return 0&printf("-1"); memset(h,-1,sizeof(h)); for(int i=1;i<=n;i++) if(i==n || a[i]^b[i]) { if(i<n) ans++; int k=hash(a[i]); if(h[k]<0) h[k]=a[i],bel[k]=++tot; k=hash(b[i]); if(h[k]<0) h[k]=b[i],bel[k]=++tot; } for(int i=1;i<=tot;i++) f[i]=i; for(int i=1;i<=n;i++) if(a[i]^b[i]) f[get(bel[hash(a[i])])]=get(bel[hash(b[i])]); for(int i=1;i<=tot;i++) if(f[i]==i) ans++; printf("%d",ans-1); return 0; }
相关文章推荐
- AtCoder Grand Contest 016
- Atcoder Grand Contest 016 F Games on DAG
- Atcoder Grand Contest 016 D XOR Replace
- AtCoder Grand Contest 016 B - Colorful Hats 乱搞
- AtCoder Grand Contest 016 C - +/- Rectangle 构造
- AtCoder Grand Contest 016 E - Poor Turkeys 贪心
- AtCoder Grand Contest 016 F - Games on DAG SG函数+状压dp
- 【题解】AtCoder Grand Contest 016
- [AtCoder Grand Contest 016] D: Xor Replace (agc016d)
- Atcoder Grand Contest 010 C - Cleaning 树贪心(伪)
- (组合计数)AtCoder Grand Contest 018 E - Sightseeing Plan
- AtCoder Grand Contest 020 B - Ice Rink Game(贪心+计算机乘法)
- AtCoder Grand Contest 020 C - Median Sum (背包问题+bitset )
- AtCoder Grand Contest 015 E - Mr.Aoki Incubator dp
- AtCoder Grand Contest 017 F - Zigzag 状压dp
- AtCoder Grand Contest 019 F - Yes or No 数学
- AtCoder Grand Contest 009 C - Division into Two 动态规划
- AtCoder Grand Contest 004 E - Salvage Robots 动态规划
- AtCoder Grand Contest 006 E - Rotate 3x3 树状数组
- [AtCoder Grand Contest 017] F: Zigzag (agc017F)