๋ฌธ์
https://www.acmicpc.net/problem/23326
๋ฐฑ์ค - ๋ฌธ์ ์ง - 0x16๊ฐ - ์ด์ง ๊ฒ์ ํธ๋ฆฌ
์๊ณ ๋ฆฌ์ฆ: ์ด์ง ๊ฒ์ ํธ๋ฆฌ, ํธ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์งํฉ๊ณผ ๋งต
ํ์ด

21944: ๋ฌธ์ ์ถ์ฒ ์์คํ Version 2์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฌดํ TLEโพ๏ธ์ ๋น ์ง๊ฒ ํ๋ ๋ ์์ด๋ค.
1๏ธโฃ ์ฒซ๋ฒ์งธ ์๋
๋ช
์๋ค์ ํ์ฌ ์์น: [ํ์ฌ ์์น์ ๋ช
์์ ๊ฑฐ๋ฆฌ๋ค] ํํ์ ๋์
๋๋ฆฌ๋ก ๊ตฌ์ฑ.
๊ฐ๊ฐ์ ๊ฐ ๋ฆฌ์คํธ๋ ์ต์ํ์ผ๋ก ์ฌ์ฉํจ.
=> ์ด๋ฆผ๋ ์์ด ์๊ฐ์ด๊ณผ
2๏ธโฃ ๋๋ฒ์งธ ์๋
์ด์งํ์ ๋ชจ๋๋ก bisect_left, insort_left ํจ์๋ฅผ ์ฌ์ฉ.
๋ช
์๋ค๋ง ๋ฐ๋ก ๋ฆฌ์คํธ์ ์ ์ฅ ํ, ์ด์งํ์์ผ๋ก ์๋ง์ ์ธ๋ฑ์ค๋ฅผ ์ฐพ์ ์ฝ์
/์ญ์ + ํ์์ ์งํํ์.
=> 66% ์ ๋๊น์ง ์งํ ํ ์๊ฐ์ด๊ณผ
Python์ผ๋ก๋ ์๋๋๊ฑด๊ฐ? ํ์ง๋ง PyPy3๋ก ํต๊ณผ๋ ๋ถ๋ค์ด ์กด์ฌํ๋ค.
๋งํ๋ค/ํ๋ ธ๋ค์ ๋ฌธ์ ๊ฐ ์๋๋ผ ๋๋ฌด ๋ต๋ตํ๊ณ ... ๊ฒฐ๊ตญ ํธ๋ฒ์ ์จ์ ํด๋ต ์ฝ๋๋ฅผ ์ฟ๋ณผ ์ ์์๋ค.(๋ค๋ฅธ ์ธ์ด๋ก ์ ์ถํด์ ํต๊ณผํ ํ ๊ณต๊ฐ๋ ํ์ด ์ฝ๋ ํ์^^;;)
๐๏ธ ์ ๋ต ํค ํฌ์ธํธ
ํด๊ฒฐ ๋ฐฉ์์ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ(Segment Tree)๋ฅผ ์ฌ์ฉํ๋๊ฒ์ด์๋ค.
์ฌ์ค ๋๋ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์ด ๋ฌธ์ ๋ก ์ฒ์ ์๊ฒ ๋์๋ค.
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋?
: ํน์ ๋ฒ์์ ๊ฐ์ ๋น ๋ฅด๊ฒ ๊ณ์ฐํ ์ ์๋๋ก ์ค๊ณ๋ ํธ๋ฆฌ ์๋ฃ๊ตฌ์กฐ
๋ฒ์๋ฅผ ์ ๋ฐ์ฉ ๋๋์ด ๋ฒ์์ ๊ฐ์ ์ ์ฅํด๋๋ ํํ๋ค.
์ํ๋๊ฐ๋ณด๋ค ํ์ฌ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ๋
ธ๋์ ๊ฐ์ด ์๊ฑฐ๋ ๊ฐ๋ค๋ฉด ์ผ์ชฝ, ํฌ๋ค๋ฉด ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํ๋ค.
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ํฌ๊ธฐ๋ ๋ณดํต 4 * ํธ๋ฆฌ์ ํฌ๊ธฐ ๋ก ์ค์ ํ๋ ํธ์ด๋ค.
๋ณธ์ธ ๋ง์๋๋ก์ง๋ง, ๋ฃจํธ๋
ธ๋๋ฅผ 1๋ก ์ก๊ณ ์์ํด์ผ ์ผ์ชฝ ์์/์ค๋ฅธ์ชฝ ์์์ ๊ตฌ๋ถํ๊ธฐ ์ฝ๋ค.
1๋ถํฐ ์์ํ ๊ฒฝ์ฐ ํ์ฌ ๋
ธ๋ ๋ฒํธ๋ฅผ node๋ผ๊ณ ํ ๋ ์ผ์ชฝ ์์์ ๋ฒํธ๋ 2 * node, ์ค๋ฅธ์ชฝ ์์์ ๋ฒํธ๋ 2 * node + 1๊ฐ ๋๋ฏ๋ก ์ฝ๊ฒ ์ ํํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด์จ๋ ์ด์ง ํ์ ํธ๋ฆฌ์ด๋ฏ๋ก ์ํ๋ ํ๊ฒ๊ฐ๊ณผ ์ผ์นํ ๋๊น์ง start + end์ ์ค๊ฐ๊ฐ mid์ ํ๊ฒ๊ฐ์ ๋น๊ตํด๋๊ฐ๋ค.
์ผ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋ ์ start๋ ๊ทธ๋๋ก, end๋ mid๋ก ์
๋ฐ์ดํธ. (์๊ฑฐ๋ ๊ฐ์ ๊ฒฝ์ฐ์ ํด๋น๋๋ฏ๋ก)
์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋ ์ start๋ mid + 1๋ก, end๋ ๊ทธ๋๋ก ์ ์งํ๋ค.
๋ง์ฝ ๋ช
์๋ค์ ์ํ๊ฐ ๋ค์๊ณผ ๊ฐ๋ค๊ณ ๊ฐ์ ํด๋ณด์.[1, 0, 0, 1, 1, 0, 1, 0] = 1: ๋ช
์, 0: ์๋ช
์
0๋ฒ์งธ ์ธ๋ฑ์ค๋ถํฐ ํ์ฌ ์์น๊น์ง์ ๋ช
์์ ๊ฐฏ์๊ฐ 3๊ฐ์ธ๋ฐ, ํ์ฌ ์์น๊ฐ ์ด๋์ธ์ง ์๊ณ ์ถ๋ค๋ฉด?
segt = [0] * 4 * 8 # ์๋ ํธ๋ฆฌํฌ๊ธฐ์ 4๋ฐฐ
segt[1] = 4 # ์ ์ฒด๋ฒ์์ ๋ช
์ ๊ฐฏ์
node = 1
start = 0
end = 7 (N-1)
mid = (start + end) // 2 # 7 // 2 = 3
# ์ผ์ชฝ ์๋ธํธ๋ฆฌ ( 2 * node )
segt[2] = 2 # 0~3 ์ ๋ช
์ ๊ฐฏ์
# ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ ( 2 * node + 1 )
segt[3] = 4 # 4~7 ์ ๋ช
์ ๊ฐฏ์
# ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ 3์ด๋ฏ๋ก ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋ํด์ผํจ.
# ์ผ์ชฝ๋ฒ์์ ๊ฐ(2)๋ฅผ ๋บ ํ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋.
# ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ 3 - 2 = 1. ์ด์ 1์ด ๋จ.
node = 3
start = mid + 1 # 4
end = 7
mid = (4 + 7) // 2 = 5
# ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ์๋ธํธ๋ฆฌ
# ์ผ์ชฝ ์๋ธํธ๋ฆฌ ( 2 * node )
segt[6] = 1 # 4~5 ์ ๋ช
์ ๊ฐฏ์
# ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ ( 2 * node + 1 )
segt[7] = 1 # 6~7 ์ ๋ช
์ ๊ฐฏ์
# segt[6] ๊ฐ๊ณผ ์ฐพ๊ณ ์ํ๋ ๊ฐ์ด ๊ฐ์ผ๋ฏ๋ก ์ผ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋
# ์ผ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋ํ๋ฏ๋ก ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ ๊ทธ๋๋ก ์ ์ง
node = 6
start = 4
end = 5
mid = (4 + 5) // 2 = 4
# ์ผ์ชฝ ์๋ธํธ๋ฆฌ
segt[12] = 1 # 4~4์ ๋ช
์ ๊ฐฏ์
# ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ
segt[13] = 0 5~5์ ๋ช
์ ๊ฐฏ์
# segt[12] ๊ฐ๊ณผ ์ฐพ๊ณ ์ํ๋ ๊ฐ์ด ๊ฐ์ผ๋ฏ๋ก ์ผ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋, ๊ฐ์ ์ ์ง
node = 12
start = 4
end = 4
# start == end ์ด๋ฏ๋ก ํ์ ์ข
๋ฃ.
์ข
๋ฃ ํ ์ต์ข
๊ฐ์ left = right = 4๊ฐ ๋๋ค.
์๋์ ๋ฆฌ์คํธ๊ฐ๊ณผ ๋น๊ตํด๋ณด๋ฉด [1, 0, 0, 1, (1), 0, 1, 0] => 4๋ฒ ์ธ๋ฑ์ค๊น์ง์ ๋ช
์ ๊ฐฏ์๋ 3, ์ต์ข
๊ฐ๊ณผ ์ผ์นํ๋๊ฒ์ ํ์ธํ ์ ์๋ค!
์์ฝํ์๋ฉด ์ํ๋ ๊ฐ์ ๊ฐ์ง ์์น๋ฅผ ์ฐพ์๋๊น์ง ๋ฒ์๋ฅผ ์ ๋ฐ์ฉ ๋๋ ๊ฐ๋ฉฐ, ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ํ๊ณ ๋๋๊ฒ์ด๋ค.
๋ช
๋ น์ด 1 ~ 4์ ์ํ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ๋ค.
(์ฐธ๊ณ ๋ก ๋๋ ๋ช
์๋ 1-based๋ก ๋ง์ถฐ์คฌ๋ค.)
๋ช ๋ น์ด == 1
- ๋ช
์์ธ๊ฒฝ์ฐ ํด์
ํด๋น ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ๋๋ฌํ ๋๊น์ง ๊ฑฐ์ณ๊ฐ๋ ๋ชจ๋ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ -1
- ๋ช
์๊ฐ ์๋๊ฒฝ์ฐ ๋ช
์๋ก ์ถ๊ฐ
ํด๋น ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ๋๋ฌํ ๋๊ฐ์ง ๊ฑฐ์ณ๊ฐ๋ ๋ชจ๋ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ +1
๋ช ๋ น์ด == 2
ํ์ฌ ์์น๋ฅผ ์ฃผ์ด์ง ๊ฐ๋งํผ ์ด๋์ํด
๋ช ๋ น์ด == 3
- ๋ช
์๊ฐ ์์ ์๋ค๋ฉด(segt[1] == 0) -1 ์ถ๋ ฅ
์๋๋ผ๋ฉด, ๋ช
์์ ๊ฐฏ์๋ฅผ ์นด์ดํธํ ๋ณ์ cnt๋ฅผ 1๋ก ์ค์ ํ ํ์ฌ์์น๊น์ง์ ๋ช
์์ ๊ฐฏ์๋ฅผ ์นด์ดํธํ๋ค.
๐ ์ 1๋ก ์ค์ ํ๋๋ฉด ๋ง์ฝ cnt = 3์ด ๋ ๊ฒฝ์ฐ, ํ์ฌ์์น๊น์ง์ ๋ช
์์ ๊ฐฏ์๋ 2๊ฐ๋ผ๋๋ป์ด๊ณ ์ฐ๋ฆฌ๊ฐ ์ฐพ์์ผ ํ ๋ช
์๋ 3๋ฒ์งธ์ ๋ช
์์ด๊ธฐ ๋๋ฌธ์ด๋ค. (0์ผ๋ก ์ค์ ํ๊ณ ๋ฐ๋ก ์ฒ๋ฆฌํด์ค๋ ๋จ)
์นด์ดํ
ํ cnt๊ฐ์ด ์ ์ฒด ๋ช
์์ ๊ฐ๋ณด๋ค ํฌ๋ค๋ฉด, ํ์ฌ ์์น ์ดํ์๋ ๋ช
์๊ฐ ์๋ค๋ ๋ป์ด๋ฏ๋ก ์ฒซ๋ฒ์งธ ๋ช
์๋ฅผ ํ๊ฒ์ผ๋ก ์ค์ ํ๋ค.(cnt = 1)
๊ทธ๋ฆฌ๊ณ cnt๊ฐ๊ณผ ์ผ์นํ๋ ๋ช
์์ ์์น๋ฅผ ์ฐพ์๋๊น์ง ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ํ๊ณ ๋ ๋ค.
๊ฐ์ ๊ตฌํ๋ค๋ฉด ๋ช
์์ ์์น๊ฐ ํ์ฌ ์์น๋ณด๋ค ํฌ๊ณ ์์์ ์๊ด์์ด, (๋ช
์์ ์์น - ํ์ฌ ์์น) % N์ ํ ๊ฒฐ๊ณผ๊ฐ์ด ๋ค์ ๋ช
์๊น์ง์ ๊ฑฐ๋ฆฌ๊ฐ์ด ๋๋ค.
์ด๊ฑด ํ์ด์ฌ์ ํน์ฑ๋์ด๋ค.
์ ์ฒด ์ฝ๋
# ๋ฉ๋ชจ๋ฆฌ: 53528KB / ์๊ฐ: 2248ms
from sys import stdin
input = stdin.readline
N, Q = map(int, input().split())
A = list(map(int, input().split()))
landmark = sum(A) # ๋ช
์์ ๊ฐฏ์
# ๋ช
์ ์
๋ฐ์ดํธ(์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ์
๋ฐ์ดํธ) ํจ์
def update(target, node, left, right):
# ํ์ฌ ๋
ธ๋ ๊ฐ ์
๋ฐ์ดํธ
seqt[node] += P # P: target์ ๋ช
์๋ก ์ถ๊ฐํ๋ค๋ฉด 1, ๋ช
์๋ฆฌ์คํธ์์ ์ญ์ ํ๋ค๋ฉด -1
if left == right:
return
mid = (left + right) // 2
if target <= mid: # ์ฐพ๋ ๋ช
์๊ฐ mid๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค๋ฉด ์ผ์ชฝ ์๋ธํธ๋ฆฌ๋ก
update(target, 2*node, left, mid)
else: # mid๋ณด๋ค ํฌ๋ค๋ฉด ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ๋ก
update(target, 2*node + 1, mid+1, right)
# ํ์ฌ ์์น๊น์ง์ ๋ช
์์ ๊ฐฏ์๋ฅผ ์นด์ดํธํ๋ ํจ์ (ํ์ฌ ์์น ํฌํจ)
def count_landmark(node, left, right):
global cnt
if left == right:
return
mid = (left + right) // 2
if curr <= mid: # ํ์ฌ ์์น๊ฐ mid๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค๋ฉด ์ผ์ชฝ ์๋ธํธ๋ฆฌ๋ก
count_landmark(2*node, left, mid)
else: # mid๋ณด๋ค ํฌ๋ค๋ฉด ์ผ์ชฝ ์๋ธํธ๋ฆฌ๊ฐ์ cnt์ ์ถ๊ฐ, ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋
cnt += seqt[2*node]
count_landmark(2*node + 1, mid+1, right)
# ๋ค์ ๋ช
์์ ์์น๋ฅผ ์ฐพ๋ ํจ์
def find_landmark(node, left, right):
global cnt, ret
if left == right:
ret = left
return
mid = (left + right) // 2
if cnt <= seqt[2*node]: # cnt๊ฐ์ด ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ๊ฐ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค๋ฉด, ์ผ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋
find_landmark(2*node, left, mid)
else: # ์ผ์ชฝ ์๋ธํธ๋ฆฌ๋ณด๋ค ํฌ๋ค๋ฉด, ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ๊ฐ์ ๋นผ๊ณ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ๋ก ์ด๋
cnt -= seqt[2*node]
find_landmark(2*node + 1, mid+1, right)
# ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ์์ฑ
seqt = [0] * (4*N)
# ๊ธฐ์กด ๋ช
์๋ค์ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ์ ์ฅ
for i in range(N):
if A[i]:
P = 1
update(i+1, 1, 1, N)
# ํ์ฌ ์์น: 1-based๋ก ๊ด๋ฆฌํจ
curr = 1
# ์ฟผ๋ฆฌ๋ฌธ ์คํ
for _ in range(Q):
cmd, *x = map(int, input().split())
# 1: ๋ช
์ toggle
if cmd == 1:
target = x[0]
# ์ด๋ฏธ ๋ช
์๋ก ์ง์ ๋ ์ฅ์๋ผ๋ฉด ์ ๊ฑฐ
if A[target-1]:
A[target-1] = 0
landmark -= 1
P = -1 # ์ ๊ฑฐํด์ค์ผ ํ๋ฏ๋ก -1๋ก ์ค์
else:
A[target-1] = 1
landmark += 1
P = +1
update(target, 1, 1, N)
# 2: ์ธ๊ฐ ์ด๋
elif cmd == 2:
dis = x[0]
curr = ((curr - 1 + dis) % N) + 1 # ํ์ฌ ์์น์์ dis๋งํผ ์ด๋
else:
# ๋ช
์๊ฐ ์์ ์๋ค๋ฉด -1 ์ถ๋ ฅ ํ ๋์ด๊ฐ
if not seqt[1]:
print(-1)
continue
cnt = 1 # ํ์ฌ ์์น ์ดํ์ cnt๋ฒ์งธ ๋ช
์
count_landmark(1, 1, N)
# ๋ง์ฝ ์นด์ดํ
ํ ๊ฒฐ๊ณผ๊ฐ์ด ์ค์ ๋ช
์์ ๊ฐฏ์+1 ์ผ๊ฒฝ์ฐ -> curr ์ดํ ๋ช
์ X, ์ฒซ๋ฒ์งธ ๋ช
์๊ฐ ์ ์ผ ๊ฐ๊น์ด ์
if cnt == landmark+1:
cnt = 1
ret = 0
find_landmark(1, 1, N)
print((ret - curr) % N)
๋๋ถ์ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์๊ฒ๋๋ค. ๊ณ ๋ง์ด ๋ ์~