結果
| 問題 |
No.1749 ラムドスウイルスの感染拡大
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-11-20 16:57:03 |
| 言語 | Crystal (1.14.0) |
| 結果 |
AC
|
| 実行時間 | 20 ms / 2,000 ms |
| コード長 | 4,518 bytes |
| コンパイル時間 | 11,542 ms |
| コンパイル使用メモリ | 301,168 KB |
| 実行使用メモリ | 13,548 KB |
| 最終ジャッジ日時 | 2024-06-11 19:03:19 |
| 合計ジャッジ時間 | 12,669 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 26 |
ソースコード
# require "crystal/graph"
# 重みなしグラフ
alias V = Int32
class Graph
getter n : Int32
getter g : Array(Array(Int32))
delegate "[]", to: g
def initialize(@n, @g)
end
def initialize(n)
@n = n.to_i
@g = Array.new(n) { [] of Int32 }
end
def initialize(n, m)
initialize(n)
m.times do |i|
yield self, i
end
end
def read
v, nv = gets.to_s.split.map(&.to_i64)
add v, nv
end
# vからnvに辺を追加する
#
# origin : 0-indexed or 1-indexed
# both : 無向グラフ、有向グラフ
def add(v, nv, origin = 1, both = true)
v = v.to_i - origin
nv = nv.to_i - origin
g[v] << nv
g[nv] << v if both
end
def bfs(root = 0)
seen = Array.new(n, false)
seen[root] = true
q = Deque.new([root])
while q.size > 0
v = q.shift
g[v].each do |nv|
next if seen[nv]
seen[nv] = true
yield v, nv
q << nv
end
end
end
# 連結成分に分解
#
# ```
# g = Graph.new(4)
# g.add 1, 2
# g.add 3, 4
# g.decomposit_connected_element # => {[0,1,0,1],[[0,1],[2,3]]
# ```
def decomposit_connected_element
seen = Array.new(n, false)
ix = [-1] * n
conn = [] of Array(Int32)
n.times do |iv|
next if seen[iv]
seen[iv] = true
ix[iv] = 0
con = [iv]
q = Deque.new([iv])
while q.size > 0
v = q.shift
g[v].each do |nv|
next if seen[nv]
seen[nv] = true
ix[nv] = con.size
con << nv
q << nv
end
end
conn << con
end
return {ix, conn}
end
# デバッグ用:アスキーアートで可視化
def debug(origin = 1, di = true)
case n
when 0
puts "++"
puts "++"
return
when 1
puts "+---+"
puts "| #{origin} |"
puts "+---+"
return
end
if di
File.open("debug.dot", "w") do |fh|
fh.puts "digraph tree {"
n.times do |v|
g[v].each do |nv|
next if v >= nv
fh.puts " #{v + origin} -- #{nv + origin};"
end
end
fh.puts "}"
end
puts `cat debug.dot | graph-easy --from=dot --as_ascii`
else
File.open("debug.dot", "w") do |fh|
fh.puts "graph tree {"
n.times do |v|
g[v].each do |nv|
# next if v >= nv
fh.puts " #{v + origin} -> #{nv + origin};"
end
end
fh.puts "}"
end
puts `cat debug.dot | graph-easy --from=dot --as_ascii`
end
end
end
# require "crystal/modint9"
# modint
struct ModInt
MAX = 1_000_000
MOD = 998_244_353_i64
class_getter f = Array(ModInt).new(MAX)
getter v : Int64
def self.f(n)
f << 1.to_m if f.empty?
f.size.upto(n) do |i|
f << f.last * i
end
f[n]
end
def self.p(n, k)
return ModInt.zero if n < k
return ModInt.zero if k < 0
n.f // (n - k).f
end
def self.c(n, k)
return ModInt.zero if n < k
return ModInt.zero if k < 0
if n <= MAX
p(n, k) // k.f
else
ans = 1.to_m
(1..k).each do |i|
ans *= (n + 1 - i)
ans //= i
end
ans
end
end
def self.h(n, k)
c(n + k - 1, k)
end
def initialize(v)
@v = v.to_i64 % MOD
end
{% for op in %w(+ - *) %}
def {{op.id}}(b)
ModInt.new(v {{op.id}} (b.to_i64 % MOD))
end
{% end %}
def **(b)
a = self
ans = 1.to_m
while b > 0
ans *= a if b.odd?
b //= 2
a *= a
end
return ans
end
def inv
self ** (MOD - 2)
end
def //(b)
self * b.to_m.inv
end
def self.zero
new(0)
end
def ==(b)
v == b.to_i64
end
def to_m
self
end
delegate to_i64, to: v
delegate to_s, to: v
delegate inspect, to: v
end
struct Int
def to_m
ModInt.new(to_i64)
end
def f
ModInt.f(self)
end
def p(k)
ModInt.p(self, k)
end
def c(k)
ModInt.c(self, k)
end
def h(k)
ModInt.h(self, k)
end
end
module Enumerable(T)
def product(initial : ModInt)
reduce(initial) { |memo, e| memo * e }
end
end
n, m, t = gets.to_s.split.map(&.to_i)
g = Graph.new(n)
m.times do
v, nv = gets.to_s.split.map(&.to_i)
g.add v, nv, origin: 0
end
# g.debug
ans = Array.new(n) { 0.to_m }
ans[0] = 1.to_m
t.times do
cnt = Array.new(n) { 0.to_m }
n.times do |v|
g[v].each do |nv|
cnt[v] += ans[nv]
end
end
n.times { |i| ans[i] = cnt[i] }
end
pp ans[0]