結果
| 問題 |
No.2325 Skill Tree
|
| コンテスト | |
| ユーザー |
navel_tos
|
| 提出日時 | 2023-05-29 20:11:14 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 2,830 ms / 3,000 ms |
| コード長 | 2,366 bytes |
| コンパイル時間 | 382 ms |
| コンパイル使用メモリ | 82,048 KB |
| 実行使用メモリ | 296,672 KB |
| 最終ジャッジ日時 | 2024-12-28 10:16:55 |
| 合計ジャッジ時間 | 64,800 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 36 |
ソースコード
#MMA Contest 015 D
'''
技がN個ある。すべての技にはレベルと技の制限がある。
たくさんクエリを送るので即答せよ。
1. レベルXのスライムは、どの技まで覚えられる?
2. 技yを覚えるために必要な最小レベルは?
とりあえず座標圧縮したくなる。
低レベルから順にシミュレーションすればいいか たぶん
クエリ2は最後にまとめて処理しよう。
技の習得フラグをどうしようかな。習得待機状態を作りたいよね。
逆辺を張っておく?「この技を覚えたら、次の技の習得判定を行う」って方式で。
'''
from collections import defaultdict as dd, deque as dq
f=lambda:list(map(int,input().split()))
#入力受取
N=int(input()); Skill=[[1,-1]]; Level=set([1]); revG=[[] for _ in range(N)]
for i in range(1,N):
L,A=f(); Skill.append([L,A-1]); Level.add(L); revG[A-1].append(i)
Q=int(input()); Query=[]
for _ in range(Q):
t,x=f()
if t==1: Query.append([t,x]); Level.add(x)
if t==2: Query.append([t,x-1])
#レベルの座標圧縮
Level=sorted(Level); D={j:i for i,j in enumerate(Level)}; Simu=[]
for i in range(N): Skill[i][0]=D[Skill[i][0]]; Simu.append((Skill[i][0],0,i))
for i in range(Q):
if Query[i][0]==1: Query[i][1]=D[Query[i][1]]; Simu.append((Query[i][1],1,i))
#下のレベルから愚直にシミュレーション
Simu=dq(sorted(Simu)); Known=[-1]*N; Ans=[0]*Q
Lv,Task,Num=Simu.popleft(); Known[0]=1; allskill=1
while Simu:
Lv,Task,Num=Simu.popleft()
if Task==0: #技の習得判定
Standby=dq()
if Known[Skill[Num][1]]<=0: Known[Num]=0 #-1はレベル不足、0は習得待機状態
if Known[Skill[Num][1]]> 0: #元の技を習得済なら
Known[Num]=Level[Lv]; allskill+=1
for next in revG[Num]:
if Known[next]==0: Standby.append(next)
while Standby: #ストックした技を習得
next=Standby.popleft()
Known[next]=Level[Lv]; allskill+=1
for go in revG[next]:
if Known[go]==0: Standby.append(go)
elif Task==1: #今覚えている技数を教える
Ans[Num]=allskill
#回答
for i in range(Q):
t,x=Query[i]
if t==1: print(Ans[i])
if t==2: print(Known[x]) if Known[x]>0 else print(-1)
navel_tos