题解
题目就是要我们求有多少个
(ai,bi)
满足
ai
xor
bi
=
2x+2y(x!=y)
所以我们可以知道:
ai
xor
bi
xor
2x
xor
2y
=0
我们就将所以
ai
xor
2x
放入一个哈希表里面,
然后枚举
bi
xor
2y
,在哈希表里面找,有多少个与它相同,统计答案。
但是这样会算重,比如:如果存在某个
ai=bj
那么就会算重位数次,
还有
ai
xor
2x
,
bi
xor
2y
与
ai
xor
2y
,
bi
xor
2x
是一样的。
那我们就强制要求
x<y
,这样计算就不会算重了。
我们先枚举位置i,从0到30,将所以
aj
xor
2i−1
放入哈希表里面,
再用所以的
bj
xor
2i
来判断,这样就不会算重了。
code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#define ll long long
#define N 100003
#define db double
#define P putchar
#define G getchar
#define mo 23332333
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
int w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=n*10+ch-'0',ch=G();
n*=w;
}
void write(int x)
{
if(x>9) write(x/10);
P(x%10+'0');
}
int f[mo],g[mo];
int a[N],b[N],z[33],root[2],tot;
int n,m,x,y;
ll ans;
inline void ins()
{
int x=y%mo;
while(f[x]!=0 && f[x]!=y)x=(x+1)%mo;
f[x]=y;g[x]++;
}
inline int find()
{
int x=y%mo;
while(f[x]!=0 && f[x]!=y)x=(x+1)%mo;
return g[x];
}
int main()
{
freopen("bipartite.in","r",stdin);
freopen("bipartite.out","w",stdout);
read(n);read(m);
for(int i=1;i<=n;i++)
read(a[i]);
for(int i=1;i<=m;i++)
read(b[i]);
z[0]=root[0]=tot=1;
for(int i=1;i<31;i++)
z[i]=z[i-1]*2;
for(int j=1;j<=n;j++)
{
y=a[j]^z[0];
ins();
}
for(int i=1;i<30;i++)
{
for(int j=1;j<=m;j++)
{
y=b[j]^z[i];
ans+=find();
//write(i),P(' '),write(j),P(' '),write(ans),P('\n');
}
for(int j=1;j<=n;j++)
{
y=a[j]^z[i];
ins();
}
}
//write(ans/2),P('\n');
printf("%lld\n",ans);
}