CF509 F - Ray in the tube
問題
y=yaとy=ybに挟まれた領域(チューブ)がある
このチューブの両側の壁上にいくつかのセンサーが付いている (x座標は非負整数)
両側の壁上の任意の格子点を2つ選び、それらを通るようなレーザーを放射するとき、最大で何個のセンサーに同時に光を入射できるか求めよ
(レーザーの光は壁に当たる度に弱まることなく反射する)
1 <= 上下それぞれの壁に付いているレーザーの個数n,m <= 10^5
0 <= レーザーの座標x <= 10^9
解法
レーザーを作る2点のx座標の差をdxとすると、dxは2のべき乗だけ試せば十分
(∵ dx = 2^k * p(:奇数)として通るセンサーはdx = 2^kとしても通るから)
座標が全部10^9以下だからdxの候補は30個くらいしかない
dxを固定したら、片側の壁はa[i]%2dx、もう片側の壁は(b[i]+dx)%2dxの値が同じセンサーは全て一本のレーザーで通れる
この値の個数をmapで数えて最大値で答えを更新していけばいい
ちなみに2つの壁のy座標は問題を解くために必要ない情報 どうでもいい
実装
両側の壁にセンサーが1個ずつあってそれらのx座標が同じときなんかは答えは2になるけど↑だけだと1になってしまう
これを防ぐために答えの初期値は2にしとく
↑で言ったdxは↓のコードではx
int n, ya, a[100100], m, yb, b[100100], res = 2, x = 1; signed main() { cin >> n >> ya; rep(i,n) cin >> a[i]; cin >> m >> yb; rep(i,m) cin >> b[i]; rep(k,31) { map<int,int> p; rep(i,n) p[a[i]%(2*x)]++; rep(i,m) p[(b[i]+x)%(2*x)]++; each(i,p) chmax(res, i.se); x *= 2; } cout << res << endl; }