結果
| 問題 |
No.230 Splarraay スプラレェーイ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2015-06-22 20:48:27 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
AC
|
| 実行時間 | 1,856 ms / 5,000 ms |
| コード長 | 4,528 bytes |
| コンパイル時間 | 270 ms |
| コンパイル使用メモリ | 12,928 KB |
| 実行使用メモリ | 18,816 KB |
| 最終ジャッジ日時 | 2024-07-07 16:43:05 |
| 合計ジャッジ時間 | 9,908 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 17 |
ソースコード
class SplayArray(object):
def __init__(self, size):
self.cell_capacity = 1024
self.capacity = self._calc_capacity(size)
self.n_cells = self.capacity // self.cell_capacity
self.values = [0] * self.n_cells
self.totals = [0] * (self.n_cells * 2)
def turn_on(self, L, R):
self._turn_on(1, self.capacity, L, R + 1)
def turn_off(self, L, R):
self._turn_off(1, self.capacity, L, R + 1)
def count(self, L, R):
return self._count(1, self.capacity, L, R + 1)
def _calc_capacity(self, size):
cap = self.cell_capacity
while cap < size:
cap <<= 1
return cap
def _turn_on(self, idx, cap, L, R):
'''
idx: self.totals 等における位置
cap: self.totals[idx] に格納できるデータの数
mid: 二分木における分水嶺に該当する値
L: 開始点
R: 終了点(Rは含まない)
'''
if self.totals[idx] == cap:
return
if L == 0 and R == cap:
self.totals[idx] = cap
return
if cap == self.cell_capacity:
idx_val = idx - self.n_cells
if self.totals[idx] == 0:
self.values[idx_val] = (1 << R) - (1 << L)
self.totals[idx] = R - L
return
self.values[idx_val] |= (1 << R) - (1 << 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 == self.cell_capacity:
idx_val = idx - self.n_cells
if self.totals[idx] == cap:
self.values[idx_val] = (1 << cap) - 1 - (1 << R) + (1 << L)
self.totals[idx] = cap - R + L
return
self.values[idx_val] &= ~((1 << R) - (1 << 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 == self.cell_capacity:
return bin((self.values[idx - self.n_cells] >> L) & ((1 << (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 sys
data = sys.stdin.readlines()
N = int(data[0])
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:
teamA.turn_on(l, r)
teamB.turn_off(l, r)
elif x == 2:
teamA.turn_off(l, r)
teamB.turn_on(l, r)
scoreA += teamA.count(0, N-1)
scoreB += teamB.count(0, N-1)
print('{} {}'.format(scoreA, scoreB))