結果
問題 |
No.2927 Reverse Polish Equation
|
ユーザー |
![]() |
提出日時 | 2025-03-20 00:17:29 |
言語 | Go (1.23.4) |
結果 |
AC
|
実行時間 | 199 ms / 2,000 ms |
コード長 | 3,368 bytes |
コンパイル時間 | 11,791 ms |
コンパイル使用メモリ | 252,316 KB |
実行使用メモリ | 14,668 KB |
最終ジャッジ日時 | 2025-03-20 00:17:48 |
合計ジャッジ時間 | 17,632 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 43 |
ソースコード
package main import . "fmt" import . "os" import bf "bufio" func main() { rd := bf.NewReader(Stdin) var q int var y int64 Fscan(rd, &q, &y) a := make([]Node, 0, q) for i := 0; i < q; i++ { var s string Fscan(rd, &s) switch s { case "+": p := len(a)-1 a[p-1] = opSum(a[p-1], a[p]) a = a[:p] case "max": p := len(a)-1 a[p-1] = opMax(a[p-1], a[p]) a = a[:p] case "min": p := len(a)-1 a[p-1] = opMin(a[p-1], a[p]) a = a[:p] case "X": a = append(a, &Value{1, 0}) default: var c int64 Sscan(s, &c) a = append(a, &Value{0, c}) } } var lower, upper int64 = -1, y+1 for lower+1<upper { middle := (lower+upper)/2 value := a[0].Calc(middle) if value < y { lower = middle } else { upper = middle } } if a[0].Calc(upper) == y { Println(upper) } else { Println(-1) } } type Node interface { Calc(x int64) int64 } type Value struct { k, c int64 } func (v *Value) Calc(x int64) int64 { return v.k*x+v.c } func (v *Value) Add(other *Value) { v.k += other.k v.c += other.c } func (v *Value) LessThan(other *Value) bool { return v.k <= other.k && v.c <= other.c } func (v *Value) GreaterThan(other *Value) bool { return v.k >= other.k && v.c >= other.c } type OpSum struct { value Value ns []Node } func (op *OpSum) Calc(x int64) int64 { sum := op.value.Calc(x) for _, n := range op.ns { sum += n.Calc(x) } return sum } func (op *OpSum) Append(ns ...Node) { for _, n := range ns { switch w := n.(type) { case *Value: op.value.Add(w) case *OpSum: op.value.Add(&w.value) op.ns = append(op.ns, w.ns...) default: op.ns = append(op.ns, n) } } } type OpMin struct { ns []Node } func (op *OpMin) Calc(x int64) int64 { res := op.ns[0].Calc(x) for _, n := range op.ns[1:] { tmp := n.Calc(x) if tmp < res { res = tmp } } return res } type OpMax struct { ns []Node } func (op *OpMax) Calc(x int64) int64 { res := op.ns[0].Calc(x) for _, n := range op.ns[1:] { tmp := n.Calc(x) if tmp > res { res = tmp } } return res } func opSum(n1, n2 Node) Node { if v1, v1ok := n1.(*Value); v1ok { if v2, v2ok := n2.(*Value); v2ok { v1.Add(v2) return v1 } } if s1, s1ok := n1.(*OpSum); s1ok { s1.Append(n2) return s1 } if s2, s2ok := n2.(*OpSum); s2ok { s2.Append(n1) return s2 } op := new(OpSum) op.Append(n1, n2) return op } func opMin(n1, n2 Node) Node { if v1, v1ok := n1.(*Value); v1ok { if v2, v2ok := n2.(*Value); v2ok { if v1.LessThan(v2) { return v1 } else if v2.LessThan(v1) { return v2 } } } if m1, m1ok := n1.(*OpMin); m1ok { if m2, m2ok := n2.(*OpMin); m2ok { m1.ns = append(m1.ns, m2.ns...) } else { m1.ns = append(m1.ns, n2) } return m1 } if m2, m2ok := n2.(*OpMin); m2ok { m2.ns = append(m2.ns, n1) return m2 } return &OpMin{ []Node{n1, n2} } } func opMax(n1, n2 Node) Node { if v1, v1ok := n1.(*Value); v1ok { if v2, v2ok := n2.(*Value); v2ok { if v1.GreaterThan(v2) { return v1 } else if v2.GreaterThan(v1) { return v2 } } } if m1, m1ok := n1.(*OpMax); m1ok { if m2, m2ok := n2.(*OpMax); m2ok { m1.ns = append(m1.ns, m2.ns...) } else { m1.ns = append(m1.ns, n2) } return m1 } if m2, m2ok := n2.(*OpMax); m2ok { m2.ns = append(m2.ns, n1) return m2 } return &OpMax{ []Node{n1, n2} } }