package main import . "fmt" import . "os" import bf "bufio" import . "sort" func main() { rd := bf.NewReader(Stdin) var n,m,c int Fscan(rd, &n,&m,&c) a := make([]int, n) for i := range a { Fscan(rd, &a[i]) } b := make([]int, m) for i := range b { Fscan(rd, &b[i]) } Ints(b) sum := 0 for i := 0; i < n; i++ { p := Search(len(b), func(k int) bool { return b[k] * a[i] > c }) sum += m - p } ans := float64(sum) / float64(m) / float64(n) Printf("%.8f\n", ans) } /* 考察 Aから1枚選ばれる確率は 1/N 選ばれたカードに書かれた数を A[i] とすると 処理するには B から B[k] * A[i] > C となる数の書かれたカードが選ばれる必要がある これはBを昇順ソートすると条件を満たす最小のB[k]以上のBの個数をMで割ったのがA[i]に対する勝率になる 答えは ans = Σ{i=1..N}( 1/N * B.count( B[k] * A[i] > C ) ) / M ) = Σ{i=1..N}( B.count( B[k] * A[i] > C) ) / M / N かなあ まぁ普通に二分探索 ああ、まぁいわゆる座標圧縮して B の値のx以上の個数の累積和を取って求めるでもいいのかもね */