不难发现起点必定是一个点。
每次间隔的距离一定是 ,关键就是要判断两点是否在同一跳跃距离上可被同时覆盖。
我们可以对上边进行 ,这样对于多个点是否可以在距离为 的情况下被同时访问做判断。我们开一个 ,用于映射这些关键值的数量。即一旦得出一个关键值,在 上进行自增即可。
Code:
#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
using namespace std;
const int maxn = 1000000 + 4;
const long long MAX = 1000000000;
long long up[maxn];
long long down[maxn];
map<long long, int> M;
inline void init(){ M.clear();}
int n,m;
long long x, y;
scanf("%d%I64d",&n,&x);
for(int i = 1;i <= n; ++i) scanf("%I64d",&up[i]);
scanf("%d%I64d",&m,&y);
for(int i = 1;i <= m; ++i) scanf("%I64d",&down[i]);
int ans = 0;
for(int i = 1;i <= n; ++i) ++M[up[i]];
for(int i = 1;i <= m; ++i) ++M[down[i]];
for(auto v : M) ans = max(ans, v.second);
for(long long dx = 1; dx <= MAX; dx <<= 1)
{
long long mod = (dx << 1);
init();
for(int i = 1;i <= n; ++i)++M[up[i] % mod];
for(int i = 1;i <= m; ++i)++M[(down[i] + dx) % mod];
for(auto v : M) ans = max(ans, v.second);
}
printf("%d",ans);
return 0;
}