結果
| 問題 |
No.1170 Never Want to Walk
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-01-19 11:21:35 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
AC
|
| 実行時間 | 830 ms / 2,000 ms |
| コード長 | 2,826 bytes |
| コンパイル時間 | 117 ms |
| コンパイル使用メモリ | 12,800 KB |
| 実行使用メモリ | 32,920 KB |
| 最終ジャッジ日時 | 2024-11-23 13:45:18 |
| 合計ジャッジ時間 | 13,904 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 37 |
ソースコード
class UnionFind:
"""
非再帰で実装
"""
def __init__(self,n):
"""
n:ノード数
"""
self.n=n
self.pr=[-1]*n # self.pr[i]:ノードiがチームの親ならメンバー数*-1の値。そうでないなら、親ノード
def union(self,x,y):
"""
xとyのチームを合体
"""
x=self.find(x)
y=self.find(y)
if x==y:return
# メンバー多い方が少ない方を取り込む.xを多い方にする
if -self.pr[x]<-self.pr[y]:
x,y=y,x
# xがyを取り込む
assert self.pr[x]<0
assert self.pr[y]<0
self.pr[x]+=self.pr[y]
self.pr[y]=x
assert self.pr[y]!=y
assert self.pr[x]!=x
def find(self,x):
"""
xの親を見つける
"""
y=x
route=[]
while self.pr[y]>=0:# 親を探す
route.append(y)
y=self.pr[y]
assert y>=0 and self.pr[y]<0
while self.pr[x]>=0:# 親を付け替える
assert y!=x
x_=self.pr[x]
self.pr[x]=y
x=x_
return y
def main1(n,a,b,x):
# 駅i<->駅s~uまで双方向に移動可能のとき,駅s-uを1つの駅とみなす->UnionFind
uf=UnionFind(n)
idx_s=0
idx_e=0
idx_uf=0
# idx_ufは直前の駅と連結している
for i in range(n):# 駅iから右方向を
while idx_s<n and x[idx_s]<x[i]+a:
idx_s+=1
if idx_s==n:break
while idx_e+1<n and x[idx_e+1]<=x[i]+b:
idx_e+=1
# idx_s ~ idx_eはギリギリ入る駅
if i==idx_e:continue
if x[i]+a<=x[idx_e]<=x[i]+b:uf.union(i,idx_e)
for j in range(max(idx_s,idx_uf),idx_e):uf.union(j,j+1)
#for j in range(idx_s,idx_e):uf.union(j,j+1)
idx_uf=idx_e
ret=[]
for i in range(n):
ret.append(-uf.pr[uf.find(i)])
return ret
def main0(n,a,b,x):
uf=UnionFind(n)
for i in range(n):
for j in range(i+1,n):
if a<=abs(x[i]-x[j])<=b:
uf.union(i,j)
ret=[]
for i in range(n):
ret.append(-uf.pr[uf.find(i)])
return ret
if __name__=='__main__':
n,a,b=map(int,input().split())
x=list(map(int,input().split()))
ret=main1(n,a,b,x)
print(*ret,sep="\n")
if __name__=='__main__1':
from random import randint,shuffle
for _ in range(100):
n=randint(1,100)
a=randint(1,100)
b=randint(a,100)
x=[randint(0,100)]
for _ in range(n):
x.append(x[-1]+randint(1,100))
ret0=main0(n,a,b,x)
ret1=main1(n,a,b,x)
if ret0!=ret1:
print(n,a,b)
print(*x)
print(ret0)
print(ret1)
exit()