Official
O - 通知/Notification Editorial by tatyam
愚直にクエリを処理すると、時間計算量が \(O(NQ+M)\) になり TLE してしまいます。
そこで、以下のようにクエリを処理します。
- ユーザ \(X_i\) の友達が \(\sqrt M\) 人未満の場合、 \(T_i=1\) のクエリで愚直に通知を配る。
- ユーザ \(X_i\) の友達が \(\sqrt M\) 人以上の場合、 \(T_i=1\) のクエリでは通知を配らず、ユーザ \(X_i\) の友達に \(T_i=2\) のクエリが来た時に取りに来てもらう。
- この処理のために、あらかじめユーザ \(x\) の友達のうち「友達が \(\sqrt M\) 人以上いるユーザ」のリストを作っておく。このリストの大きさは \(O(\sqrt M)\) である。
このようにすることで、時間計算量が \(O((M+Q)\sqrt M+N)\) になり、十分高速に処理することができます。
回答例 (Python)
N, M = map(int, input().split())
g = [list() for i in range(N)]
for i in range(M):
A, B = map(int, input().split())
A -= 1
B -= 1
g[A].append(B)
g[B].append(A)
rt = int(M ** 0.5)
g_high = [list(x for x in g[i] if len(g[x]) >= rt) for i in range(N)]
cnt_low = [0] * N
cnt_high = [0] * N
before = [0] * N
Q = int(input())
for _ in range(Q):
T, X = map(int, input().split())
X -= 1
if T == 1:
if len(g[X]) < rt:
for at in g[X]:
cnt_low[at] += 1
else:
cnt_high[X] += 1
else:
ans = cnt_low[X]
for at in g_high[X]:
ans += cnt_high[at]
print(ans - before[X])
before[X] = ans
posted:
last update: