Alice 参加了一场考试。这场考试共有 n^2 道题,题目在答题卡上排列成一个 n * n 的矩阵。
Alice 聪明地找到了题目的答案的规律。具体地,(i,j) 位置上的答案为 ai ^ bj 。
然而,Alice 把答案的行列涂反了。即第 i 行第 j 列的答案填涂到了第 j 行第 i 列。
请问 Alice 能答对多少道题。(双循环暴力会超时哦!!)
Input
第一行一个整数 n (1 ≤ n ≤ 3e5).
第二行 n 个整数 a1,a2,……,an (0 ≤ ai ≤ 1e9).
第三行 n 个整数 b1,b2,……,bn (0 ≤ bi ≤ 1e9).
Output
输出一个数,即 Alice 答对的题目数量.
输入
4
1 2 3 4
2 4 3 4
输出
6
样例:
正确答案 填涂答案
3525 3016
0616 5670
1707 2107
6070 5670
解析:
(i,j),(j,i) 位置的答案相同,等价于 ai ^ bj == aj ^ bi
利用异或性质,可得 ai ^ bi == aj ^bj ,即统计有多少个不同 ai ^ bi 的个数
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
typedef pair<int,int> PII;
const int N=2e6+10;
int a[N],b[N],p[N];
int n,cnt;
map <int,int> s;
int get(int x)
{
if (s.count(x)==0) s[x]=++cnt;
return s[x];
}
signed main()
{
ios;
cin>>n;
for (int i=0;i<n;i++) cin>>a[i];
for (int i=0;i<n;i++) cin>>b[i];
for (int i=0;i<n;i++)
{
int k=(a[i]^b[i]);
k=get(k);
p[k]++;
}
int ans=0;
for (int i=1;i<=cnt;i++) ans +=p[i]*p[i];
cout<<ans;
return 0;
}