結果
| 問題 |
No.1750 ラムドスウイルスの感染拡大-hard
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-11-20 17:46:32 |
| 言語 | Crystal (1.14.0) |
| 結果 |
AC
|
| 実行時間 | 528 ms / 2,000 ms |
| コード長 | 2,876 bytes |
| コンパイル時間 | 11,989 ms |
| コンパイル使用メモリ | 301,752 KB |
| 実行使用メモリ | 13,824 KB |
| 最終ジャッジ日時 | 2024-06-11 20:02:12 |
| 合計ジャッジ時間 | 18,518 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 30 |
ソースコード
# require "crystal/matrix"
class Matrix(T)
getter n : Int32
getter a : Array(Array(T))
def self.zero(n)
new(n) { T.zero }
end
def self.eye(n)
new(n) { |i, j| i == j ? T.zero + 1 : T.zero }
end
def initialize(n)
@n = n.to_i
@a = Array.new(n) { |i| Array.new(n) { |j| yield i, j } }
end
def initialize(@a)
@n = a.size
end
def *(b : self) : self
Matrix(T).new(n) do |i, j|
ans = T.zero
n.times do |k|
ans += self[i, k] * b[k, j]
end
ans
end
end
def *(b : Array(Int))
a.map do |v|
v.zip(b).sum { |x, y| x*y }
end
end
def **(k : Int) : self
ans = Matrix(T).eye(n)
m = Math.ilogb(k) + 1
b = dup
m.times do |i|
ans *= b if (k >> i).odd?
b *= b
end
ans
end
def inv
b = a.zip(Matrix(T).eye(n).a).map { |u, v| u + v }
end
@[AlwaysInline]
def [](i, j)
a[i][j]
end
@[AlwaysInline]
def []=(i, j, x)
a[i][j] = x
end
def ==(b : self) : Bool
n.times.all? do |i|
n.times.all? do |j|
self[i, j] == b[i, j]
end
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_i64)
g = Matrix(ModInt).zero(n)
m.times do
v, nv = gets.to_s.split.map(&.to_i)
g[v,nv] = 1.to_m
g[nv,v] = 1.to_m
end
g = g ** t
pp g[0,0]
# pp g