結果

問題 No.1557 Binary Variable
コンテスト
ユーザー ID 21712
提出日時 2026-05-21 18:55:05
言語 Go
(1.26.1)
コンパイル:
env GOCACHE=/tmp go build _filename_
実行:
./Main
結果
RE  
実行時間 -
コード長 2,604 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 12,893 ms
コンパイル使用メモリ 269,276 KB
実行使用メモリ 22,236 KB
最終ジャッジ日時 2026-05-21 18:57:02
合計ジャッジ時間 36,008 ms
ジャッジサーバーID
(参考情報)
judge1_0 / judge2_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample -- * 3
other AC * 5 RE * 14 TLE * 1 -- * 14
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

package main

import . "fmt"
import . "os"
import bf "bufio"
import . "sort"

type T struct {
	v,index,side int
}

func main() {
	rd:=bf.NewReader(Stdin)
	var n,m int
	Fscan(rd,&n,&m)
	ls := make([]int, n)
	rs := make([]int, n)
	for i := range ls {
		Fscan(rd,&ls[i], &rs[i])
	}
	ans := solve(n, m, ls, rs) 
	Println(ans)
}

func solve(n,m int, ls, rs []int) int {
	ts := make([]*T, 0, m*2)
	for i := 0; i < m; i++ {
		L := &T{ ls[i], i, 0 }
		R := &T{ rs[i], i, 1 }
		ts = append(ts, L, R)
	}
	Slice(ts, func(i, j int) bool {
		d := ts[i].v - ts[j].v
		if d == 0 {
			return ts[i].side < ts[j].side
		} else {
			return d < 0
		}
	})
	removed := make([]bool, m)
	current := []*T{}
	zeros := 0
	for len(ts) > 0 {
		t := ts[0]
		ts = ts[1:]
		if t.side == 0 {
			current = append(current, t)
		} else if !removed[t.index] {
			zeros++
			for _, c := range current {
				removed[c.index] = true
			}
			current = current[:0]
		}
	}
	return n-zeros
}

func init() {
	check()
}

func check() {
	const n = 10
	const m = 5
	ls := make([]int, m)
	rs := make([]int, m)
	used := make([]bool, n+1)
	cnt := 0
	var tes func(i int)
	tes = func(i int) {
		if i == m {
			cnt++
			ans := solve(n, m, ls, rs)
			expect := bruteforce(n, m, ls, rs)
			if ans != expect {
				println("n=",n)
				println("m=",m)
				println(Sprintf("ls=%#v", ls))
				println(Sprintf("rs=%#v", rs))
				println("ans=",ans)
				println("expect=",expect)
				panic("bug")
			}
			return
		}
		for x := 1; x <= n; x++ {
			if used[x] {
				continue
			}
			for y := x; y <= n; y++ {
				if used[y] {
					continue
				}
				ls[i] = x
				rs[i] = y
				used[x] = true
				used[y] = true
				tes(i+1)
				used[x] = false
				used[y] = false
			}
			break
		}
	}
	
	tes(0)
	println("cnt=",cnt)
}

func bruteforce(n,m int, ls,rs []int) int {
	ans := 0
	for i := 0; i < (1 << n); i++ {
		zerosum := make([]int, n+1)
		for k,v := 0,i; k < n; k++ {
			if (v&1) != 0 {
				zerosum[k+1] = 1
			}
			v >>= 1
		}
		for k := 0; k < n; k++ {
			zerosum[k+1] += zerosum[k]
		}
		ok := true
		for j := 0; j < m; j++ {
			cnt := zerosum[rs[j]]-zerosum[ls[j]-1]
			if cnt == 0 {
				ok = false
				break
			}
		}
		if !ok {
			continue
		}
		ans = max(ans, n-zerosum[n])
	}
	return ans
}

/*
考察

LからRまでに0となるBが1つ以上あるようにする必要がある
Lの小さい組から拾っていき拾ったうちのどれかのRが来たらそこを0にして拾ったやつを全部破棄、という貪欲法(?)で求まる?
LとRが同じ値のがあるときLを先に処理する必要がある(サンプルが優しい)


*/
0