原题链接:http://codeforces.com/contest/1041/problem/F
Ray in the tube
You are given a tube which is reflective inside represented as two non-coinciding, but parallel to O x Ox Ox lines. Each line has some special integer points — positions of sensors on sides of the tube.
You are going to emit a laser ray in the tube. To do so, you have to choose two integer points A A A and B B B on the first and the second line respectively (coordinates can be negative): the point A A A is responsible for the position of the laser, and the point B B B — for the direction of the laser ray. The laser ray is a ray starting at A A A and directed at B B B which will reflect from the sides of the tube (it doesn’t matter if there are any sensors at a reflection point or not). A sensor will only register the ray if the ray hits exactly at the position of the sensor.
Examples of laser rays. Note that image contains two examples. The 3 3 3 sensors (denoted by black bold points on the tube sides) will register the blue ray but only 2 2 2will register the red.
Calculate the maximum number of sensors which can register your ray if you choose points A A A and B B B on the first and the second lines respectively.
Input
The first line contains two integers n n n and y 1 ( 1 ≤ n ≤ 1 0 5 , 0 ≤ y 1 ≤ 1 0 9 ) y_1 (1≤n≤10^5, 0≤y_1≤10^9) y1(1≤n≤105,0≤y1≤109) — number of sensors on the first line and its y y y coordinate.
The second line contains n n n integers a 1 , a 2 , ⋯   , a n ( 0 ≤ a i ≤ 1 0 9 ) a_1,a_2,\cdots,a_n (0≤a_i≤10^9) a1,a2,⋯,an(0≤ai≤109) — x x x coordinates of the sensors on the first line in the ascending order.
The third line contains two integers m m m and y 2 ( 1 ≤ m ≤ 1 0 5 , y 1 < y 2 ≤ 1 0 9 ) y_2 (1≤m≤10^5, y_1<y_2≤10^9) y2(1≤m≤105,y1<y2≤109) — number of sensors on the second line and its y y y coordinate.
The fourth line contains m m m integers b 1 , b 2 , ⋯   , b m ( 0 ≤ b i ≤ 1 0 9 ) b_1,b_2,\cdots,b_m (0≤b_i≤10^9) b1,b2,⋯,bm(0≤bi≤109) — x x x coordinates of the sensors on the second line in the ascending order.
Output
Print the only integer — the maximum number of sensors which can register the ray.
Example
input
3 1
1 5 6
1 3
3
output
3
Note
One of the solutions illustrated on the image by pair A 2 A_2 A2 and B 2 B_2 B2.
题解
如果在实数域做的话,我们可以从一个无限接近于 9 0 ∘ 90^\circ 90∘的角度发出射线,这样整个管子都是射线岂不是很棒?
然而放到整数域的话,我们能做到的最极限角度就是步长为 1 1 1了,这样由于反射问题,在同一侧管壁上射线就是两个点两个点的跳的,导致有一半的整点达不到:
谁能填这些空呢?我们试试步长为 2 2 2的射线:
发现只填了一半的空,再试试步长为 3 3 3的,发现被步长为 1 1 1完虐,而步长为 4 4 4的射线又可以填掉一半的空。。。以此类推,可以发现只有步长为 2 n 2^n 2n的射线可以到达一些其他线到不了的点,除此之外的步长都严格劣于 2 n 2^n 2n(即其他步长能到达的点集都会被一个步长为 2 n 2^n 2n的射线能到达的点集严格包含)。
那么我们就只需要枚举步长为 2 n 2^n 2n的射线了,对于同侧的点,只要 m o d mod mod二倍步长同余就说明在同一射线上,对于异侧的点则需要先加上步长再取模。
由于模数较大而 n , m n,m n,m很小,可以用 m a p map map来统计。
代码
学习了一波读入姿势,感觉很强。
#include<bits/stdc++.h>
using namespace std;
const int M=1e5+5;
int up[M],down[M],ans=2,n,m;
map<int,int>mp;
void in(){scanf("%d%*d",&n);for(int i=1;i<=n;++i)scanf("%d",&up[i]);scanf("%d%*d",&m);for(int i=1;i<=m;++i)scanf("%d",&down[i]);}
void ac()
{
for(int d=2;d<=1e9;d<<=1)
{
mp.clear();
for(int i=1;i<=n;++i)++mp[up[i]%d],ans=max(ans,mp[up[i]%d]);
for(int i=1;i<=m;++i)++mp[(down[i]+(d>>1))%d],ans=max(ans,mp[(down[i]+(d>>1))%d]);
}
printf("%d",ans);
}
int main(){in();ac();}