結果
| 問題 | No.3507 RangeSum RangeUpdate RangeSqrt |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-04-19 12:31:46 |
| 言語 | Python3 (3.14.3 + numpy 2.4.4 + scipy 1.17.1) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,731 bytes |
| 記録 | |
| コンパイル時間 | 542 ms |
| コンパイル使用メモリ | 20,828 KB |
| 実行使用メモリ | 52,140 KB |
| 最終ジャッジ日時 | 2026-04-19 12:39:24 |
| 合計ジャッジ時間 | 13,508 ms |
|
ジャッジサーバーID (参考情報) |
judge2_1 / judge1_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 1 |
| other | TLE * 3 -- * 26 |
ソースコード
import sys
from math import isqrt
def main():
data = sys.stdin.buffer.read().split()
idx = 0
n, q = int(data[idx]), int(data[idx+1]); idx += 2
A = [int(data[idx+i]) for i in range(n)]; idx += n
size = 1
while size < n:
size <<= 1
INF = -1
sm = [0] * (2 * size)
mn = [0] * (2 * size)
mx = [0] * (2 * size)
lazy = [INF] * (2 * size)
for i in range(n):
sm[size+i] = mn[size+i] = mx[size+i] = A[i]
for i in range(size-1, 0, -1):
sm[i] = sm[2*i] + sm[2*i+1]
mn[i] = min(mn[2*i], mn[2*i+1])
mx[i] = max(mx[2*i], mx[2*i+1])
def apply_node(v, l, r, val):
sm[v] = val * (r - l)
mn[v] = val
mx[v] = val
lazy[v] = val
def push(v, l, r):
if lazy[v] != INF:
mid = (l + r) >> 1
apply_node(2*v, l, mid, lazy[v])
apply_node(2*v+1, mid, r, lazy[v])
lazy[v] = INF
def pull(v):
sm[v] = sm[2*v] + sm[2*v+1]
mn[v] = min(mn[2*v], mn[2*v+1])
mx[v] = max(mx[2*v], mx[2*v+1])
def node_range(v):
depth = v.bit_length() - 1
seg_size = size >> depth
pos = v - (1 << depth)
return pos * seg_size, pos * seg_size + seg_size
def push_path(ql, qr):
nodes = []
lo, hi = ql + size, qr + size
lo >>= 1; hi = (hi-1) >> 1
while lo > 0:
nodes.append(lo)
nodes.append(hi)
lo >>= 1; hi >>= 1
for v in reversed(nodes):
l, r = node_range(v)
push(v, l, r)
def query_sum(ql, qr):
push_path(ql, qr)
res = 0
l, r = ql + size, qr + size
while l < r:
if l & 1: res += sm[l]; l += 1
if r & 1: r -= 1; res += sm[r]
l >>= 1; r >>= 1
return res
def update_assign(ql, qr, val):
push_path(ql, qr)
l, r = ql + size, qr + size
l0, r0 = l, r
while l < r:
if l & 1:
nl, nr = node_range(l)
apply_node(l, nl, nr, val); l += 1
if r & 1:
r -= 1
nl, nr = node_range(r)
apply_node(r, nl, nr, val)
l >>= 1; r >>= 1
l, r = l0 >> 1, (r0-1) >> 1
while l > 0:
if lazy[l] == INF: pull(l)
if lazy[r] == INF: pull(r)
l >>= 1; r >>= 1
def update_isqrt_range(ql, qr):
stack = [(1, 0, size, False)]
while stack:
v, l, r, returning = stack.pop()
if returning:
pull(v)
continue
if ql >= r or l >= qr:
continue
sq_mn = isqrt(mn[v])
sq_mx = isqrt(mx[v])
if ql <= l and r <= qr and sq_mn == sq_mx:
apply_node(v, l, r, sq_mn)
continue
if l + 1 == r:
sm[v] = mn[v] = mx[v] = sq_mn
lazy[v] = INF
continue
push(v, l, r)
mid = (l + r) >> 1
stack.append((v, l, r, True))
stack.append((2*v+1, mid, r, False))
stack.append((2*v, l, mid, False))
out = []
for _ in range(q):
t = int(data[idx]); idx += 1
if t == 0:
l, r = int(data[idx]), int(data[idx+1]); idx += 2
out.append(query_sum(l, r))
elif t == 1:
l, r, x = int(data[idx]), int(data[idx+1]), int(data[idx+2]); idx += 3
update_assign(l, r, x)
else:
l, r = int(data[idx]), int(data[idx+1]); idx += 2
update_isqrt_range(l, r)
sys.stdout.write('\n'.join(map(str, out)) + '\n')
main()