結果

問題 No.1095 Smallest Kadomatsu Subsequence
ユーザー aru aruaru aru
提出日時 2020-09-21 15:22:34
言語 Go
(1.22.1)
結果
AC  
実行時間 729 ms / 2,000 ms
コード長 4,833 bytes
コンパイル時間 11,439 ms
コンパイル使用メモリ 213,956 KB
実行使用メモリ 25,180 KB
最終ジャッジ日時 2023-09-06 17:08:04
合計ジャッジ時間 17,777 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,380 KB
testcase_01 AC 1 ms
4,380 KB
testcase_02 AC 1 ms
4,500 KB
testcase_03 AC 1 ms
4,376 KB
testcase_04 AC 1 ms
4,380 KB
testcase_05 AC 1 ms
4,380 KB
testcase_06 AC 1 ms
4,376 KB
testcase_07 AC 1 ms
4,380 KB
testcase_08 AC 2 ms
4,380 KB
testcase_09 AC 1 ms
4,376 KB
testcase_10 AC 1 ms
4,380 KB
testcase_11 AC 1 ms
4,380 KB
testcase_12 AC 2 ms
4,380 KB
testcase_13 AC 13 ms
4,376 KB
testcase_14 AC 13 ms
4,376 KB
testcase_15 AC 12 ms
4,376 KB
testcase_16 AC 12 ms
4,376 KB
testcase_17 AC 12 ms
4,380 KB
testcase_18 AC 12 ms
4,376 KB
testcase_19 AC 13 ms
4,376 KB
testcase_20 AC 13 ms
4,380 KB
testcase_21 AC 13 ms
4,376 KB
testcase_22 AC 13 ms
4,376 KB
testcase_23 AC 571 ms
23,008 KB
testcase_24 AC 585 ms
23,036 KB
testcase_25 AC 580 ms
20,940 KB
testcase_26 AC 576 ms
20,932 KB
testcase_27 AC 729 ms
23,012 KB
testcase_28 AC 167 ms
25,180 KB
testcase_29 AC 170 ms
23,096 KB
testcase_30 AC 384 ms
20,916 KB
testcase_31 AC 361 ms
20,932 KB
testcase_32 AC 359 ms
23,052 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"sort"
	"strconv"
	"strings"
)

func out(x ...interface{}) {
	fmt.Println(x...)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getInts(N int) []int {
	ret := make([]int, N)
	for i := 0; i < N; i++ {
		ret[i] = getInt()
	}
	return ret
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

// min, max, asub, absなど基本関数
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func asub(a, b int) int {
	if a > b {
		return a - b
	}
	return b - a
}

func abs(a int) int {
	if a >= 0 {
		return a
	}
	return -a
}

func lowerBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] >= x
	})
	return idx
}

func upperBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] > x
	})
	return idx
}

// 平衡二分探索木
var (
	y uint = 88172645463325252
)

const inf = math.MaxInt64

func xorshift() uint {
	y ^= y << 7
	y ^= y >> 9
	return y
}

type treapNode struct {
	value    int
	priority uint
	count    int
	left     *treapNode
	right    *treapNode
}

func newTreapNode(v int) *treapNode {
	return &treapNode{v, xorshift(), 1, nil, nil}
}

func treapRotateRight(n *treapNode) *treapNode {
	l := n.left
	n.left = l.right
	l.right = n
	return l
}

func treapRotateLeft(n *treapNode) *treapNode {
	r := n.right
	n.right = r.left
	r.left = n
	return r
}

func treapInsert(n *treapNode, v int) *treapNode {
	if n == nil {
		return newTreapNode(v)
	}
	if n.value == v {
		n.count++
		return n
	}
	if n.value > v {
		n.left = treapInsert(n.left, v)
		if n.priority > n.left.priority {
			n = treapRotateRight(n)
		}
	} else {
		n.right = treapInsert(n.right, v)
		if n.priority > n.right.priority {
			n = treapRotateLeft(n)
		}
	}
	return n
}

func treapDelete(n *treapNode, v int) *treapNode {
	if n == nil {
		panic("node is not found!")
	}
	if n.value > v {
		n.left = treapDelete(n.left, v)
		return n
	}
	if n.value < v {
		n.right = treapDelete(n.right, v)
		return n
	}

	// n.value == v
	if n.count > 1 {
		n.count--
		return n
	}

	if n.left == nil && n.right == nil {
		return nil
	}

	if n.left == nil {
		n = treapRotateLeft(n)
	} else if n.right == nil {
		n = treapRotateRight(n)
	} else {
		// n.left != nil && n.right != nil
		if n.left.priority < n.right.priority {
			n = treapRotateRight(n)
		} else {
			n = treapRotateLeft(n)
		}
	}
	return treapDelete(n, v)
}

func treapCount(n *treapNode) int {
	if n == nil {
		return 0
	}
	return n.count + treapCount(n.left) + treapCount(n.right)
}

func treapString(n *treapNode) string {
	if n == nil {
		return ""
	}
	result := make([]string, 0)
	if n.left != nil {
		result = append(result, treapString(n.left))
	}
	result = append(result, fmt.Sprintf("%d:%d", n.value, n.count))
	if n.right != nil {
		result = append(result, treapString(n.right))
	}
	return strings.Join(result, " ")
}

func treapMin(n *treapNode) int {
	if n.left != nil {
		return treapMin(n.left)
	}
	return n.value
}

func treapLEMax(n *treapNode, v int) int {
	ret := -inf
	t := n
	for t != nil {
		if t.value <= v {
			ret = max(ret, t.value)
		}
		if t.value > v {
			t = t.left
		} else {
			t = t.right
		}
	}

	return ret
}

func treapGEMin(n *treapNode, v int) int {
	ret := inf
	t := n
	for t != nil {
		if t.value >= v {
			ret = min(ret, t.value)
		}
		if t.value < v {
			t = t.right
		} else {
			t = t.left
		}
	}

	return ret
}

func treapMax(n *treapNode) int {
	if n.right != nil {
		return treapMax(n.right)
	}
	return n.value
}

type treap struct {
	root *treapNode
	size int
}

func (t *treap) Insert(v int) {
	t.root = treapInsert(t.root, v)
	t.size++
}

func (t *treap) Delete(v int) {
	t.root = treapDelete(t.root, v)
	t.size--
}

func (t *treap) String() string {
	return treapString(t.root)
}

func (t *treap) Count() int {
	return t.size
}

func (t *treap) Min() int {
	return treapMin(t.root)
}

func (t *treap) LEMax(v int) int {
	return treapLEMax(t.root, v)
}

func (t *treap) Max() int {
	return treapMax(t.root)
}

func (t *treap) GEMin(v int) int {
	return treapGEMin(t.root, v)
}

func main() {
	sc.Split(bufio.ScanWords)
	sc.Buffer([]byte{}, 1000000)
	N := getInt()
	A := getInts(N)

	lt := &treap{}
	rt := &treap{}

	lt.Insert(A[0])
	for i := 2; i < N; i++ {
		rt.Insert(A[i])
	}
	result := inf
	for i := 1; i < N-1; i++ {
		a := lt.Min()
		b := rt.Min()
		if a < A[i] && b < A[i] {
			result = min(result, a+b+A[i])
		}
		c := lt.GEMin(A[i])
		d := rt.GEMin(A[i])
		if c != inf && d != inf && c > A[i] && d > A[i] {
			result = min(result, c+d+A[i])
		}
		lt.Insert(A[i])
		rt.Delete(A[i+1])
	}
	if result == inf {
		out(-1)
		return
	}
	out(result)
}
0