結果
| 問題 |
No.230 Splarraay スプラレェーイ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2015-06-23 01:41:05 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 2,244 ms / 5,000 ms |
| コード長 | 4,672 bytes |
| コンパイル時間 | 219 ms |
| コンパイル使用メモリ | 82,160 KB |
| 実行使用メモリ | 110,152 KB |
| 最終ジャッジ日時 | 2024-07-07 17:01:00 |
| 合計ジャッジ時間 | 15,312 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 17 |
ソースコード
class SplayArray(object):
def __init__(self, size):
self.pow2s = [1 << i for i in range(1025)]
# self.cell_capacity = 1024
self.size = size
self.capacity = self._calc_capacity(size)
self.n_cells = self.capacity // 1024 # self.cell_capacity
self.values = [0] * self.n_cells
self.totals = [0] * (self.n_cells * 2)
def count(self, L, R):
if L == 0 and R == self.size - 1: # その場しのぎの challenge01 対策
return self.totals[1]
return self._count(1, self.capacity, L, R + 1)
def _calc_capacity(self, size):
cap = 1024 # self.cell_capacity
while cap < size:
cap <<= 1
return cap
def _turn_on(self, idx, cap, L, R):
if self.totals[idx] == cap:
return
if L == 0 and R == cap:
self.totals[idx] = cap
return
if cap == 1024: # self.cell_capacity:
idx_val = idx - self.n_cells
if self.totals[idx] == 0:
self.values[idx_val] = self.pow2s[R] - self.pow2s[L]
self.totals[idx] = R - L
return
self.values[idx_val] |= self.pow2s[R] - self.pow2s[L]
self.totals[idx] = bin(self.values[idx_val]).count('1')
return
left = idx << 1
right = left + 1
if self.totals[idx] == 0:
self.totals[left] = 0
self.totals[right] = 0
mid = cap >> 1
if R <= mid:
self._turn_on(left, mid, L, R)
elif L >= mid:
self._turn_on(right, mid, L - mid, R - mid)
else:
self._turn_on(left, mid, L, mid)
self._turn_on(right, mid, 0, R - mid)
self.totals[idx] = self.totals[left] + self.totals[right]
def _turn_off(self, idx, cap, L, R):
if self.totals[idx] == 0:
return
if L == 0 and R == cap:
self.totals[idx] = 0
return
if cap == 1024: # self.cell_capacity:
idx_val = idx - self.n_cells
if self.totals[idx] == cap:
self.values[idx_val] = self.pow2s[cap] - 1 - self.pow2s[R] + self.pow2s[L]
self.totals[idx] = cap - R + L
return
self.values[idx_val] &= ~(self.pow2s[R] - self.pow2s[L])
self.totals[idx] = bin(self.values[idx_val]).count('1')
return
left = idx << 1
right = left + 1
mid = cap >> 1
if self.totals[idx] == cap:
self.totals[left] = mid
self.totals[right] = mid
if R <= mid:
self._turn_off(left, mid, L, R)
elif L >= mid:
self._turn_off(right, mid, L - mid, R - mid)
else:
self._turn_off(left, mid, L, mid)
self._turn_off(right, mid, 0, R - mid)
self.totals[idx] = self.totals[left] + self.totals[right]
def _count(self, idx, cap, L, R):
if self.totals[idx] == 0:
return 0
if self.totals[idx] == cap:
return R - L
if L == 0 and R == cap:
return self.totals[idx]
if cap == 1024: # self.cell_capacity:
return bin((self.values[idx - self.n_cells] >> L) & (self.pow2s[R - L] - 1)).count('1')
left = idx << 1
right = left + 1
mid = cap >> 1
if R <= mid:
return self._count(left, mid, L, R)
if L >= mid:
return self._count(right, mid, L - mid, R - mid)
return self._count(left, mid, L, mid) + self._count(right, mid, 0, R - mid)
if __name__ == '__main__':
# import time
# start = time.time()
# file = 'test_in/4_random_2746.txt'
# f = open(file)
# data = f.readlines()
import sys
data = sys.stdin.readlines()
N = int(data[0])
cap = 1024
while cap < N:
cap <<= 1
Q = int(data[1])
teamA = SplayArray(N)
teamB = SplayArray(N)
scoreA = 0
scoreB = 0
for line in data[2:Q + 2]:
x, l, r = map(int, line.split())
if x == 0:
bonusA = teamA.count(l, r)
bonusB = teamB.count(l, r)
if bonusA > bonusB:
scoreA += bonusA
elif bonusA < bonusB:
scoreB += bonusB
elif x == 1:
r += 1
teamA._turn_on(1, cap, l, r)
teamB._turn_off(1, cap, l, r)
else:
r += 1
teamA._turn_off(1, cap, l, r)
teamB._turn_on(1, cap, l, r)
scoreA += teamA.count(0, N-1)
scoreB += teamB.count(0, N-1)
print('{} {}'.format(scoreA, scoreB))
# print(time.time() - start)