結果
| 問題 |
No.2657 Falling Block Game
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-03-01 22:09:06 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 615 ms / 2,000 ms |
| コード長 | 2,555 bytes |
| コンパイル時間 | 239 ms |
| コンパイル使用メモリ | 82,376 KB |
| 実行使用メモリ | 118,920 KB |
| 最終ジャッジ日時 | 2024-09-29 14:08:19 |
| 合計ジャッジ時間 | 19,136 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 37 |
ソースコード
import sys
from itertools import permutations
from heapq import heappop,heappush
from collections import deque
import random
import bisect
input = lambda :sys.stdin.readline().rstrip()
mi = lambda :map(int,input().split())
li = lambda :list(mi())
class deletable_pq:
def __init__(self):
self.pq = []
self.delete_pq = []
def pop(self):
while self.pq and self.delete_pq and self.pq[0] == self.delete_pq[0]:
heappop(self.pq)
heappop(self.delete_pq)
if not self.pq:
assert False
return -heappop(self.pq)
def top(self):
while self.pq and self.delete_pq and self.pq[0] == self.delete_pq[0]:
heappop(self.pq)
heappop(self.delete_pq)
if not self.pq:
return -1
return -self.pq[0]
def add(self,val):
heappush(self.pq,-val)
def remove(self,val):
heappush(self.delete_pq,-val)
def debug(self):
print(self.pq,self.delete_pq)
class DualSegmentTree:
def __init__(self, n):
self.num = 1 << (n - 1).bit_length()
self.tree = [2*10**9 for i in range(2*self.num)]
def update(self,l,r,x):
l += self.num
r += self.num
while l < r:
if l & 1:
self.tree[l] = min(self.tree[l],x)
l += 1
if r & 1:
self.tree[r-1] = min(self.tree[r-1],x)
l >>= 1
r >>= 1
def __getitem__(self,idx):
idx += self.num
res = 2*10**9
while idx:
res = min(res,self.tree[idx])
idx>>=1
return res
H,W = mi()
S = [input() for i in range(H)]
INF = 10**9
dp = [0] * W
for i in range(H-1)[::-1]:
dec_min = DualSegmentTree(W)
inc_min = DualSegmentTree(W)
const_min = DualSegmentTree(W)
left = [j for j in range(W)]
for j in range(1,W):
if S[i][j-1] == "." and S[i][j] == ".":
left[j] = left[j-1]
right = [j for j in range(W)]
for j in range(W-1)[::-1]:
if S[i][j+1] == "." and S[i][j] == ".":
right[j] = right[j+1]
for j in range(W):
if S[i+1][j] == "#" or S[i][j] == "#":
continue
k = dp[j]
L,R = max(left[j],j-k),min(right[j],j+k)
#print(L,R,k)
const_min.update(L,R+1,k)
dec_min.update(left[j],L,j)
inc_min.update(R+1,right[j]+1,-j)
dp = [min(dec_min[j]-j,j+inc_min[j],const_min[j],INF) for j in range(W)]
#print(i,dp)
print(*dp,sep="\n")