Skip to content

Commit

Permalink
aaa
Browse files Browse the repository at this point in the history
  • Loading branch information
WangSenyuan committed Jun 6, 2024
1 parent dc69dfd commit 9348480
Show file tree
Hide file tree
Showing 5 changed files with 353 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/codeforces/set1/set19/set197/set1970/e1/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Harry Potter is hiking in the Alps surrounding Lake Geneva. In this area there are 𝑚
cabins, numbered 1 to 𝑚
. Each cabin is connected, with one or more trails, to a central meeting point next to the lake. Each trail is either short or long. Cabin 𝑖
is connected with 𝑠𝑖
short trails and 𝑙𝑖
long trails to the lake.

Each day, Harry walks a trail from the cabin where he currently is to Lake Geneva, and then from there he walks a trail to any of the 𝑚
cabins (including the one he started in). However, as he has to finish the hike in a day, at least one of the two trails has to be short.

How many possible combinations of trails can Harry take if he starts in cabin 1 and walks for 𝑛
days?

Give the answer modulo 109+7
.


### ideas
1. 如果 n = 1? 如果他选择short, 那么有 s1, * sum(li) + l1 * sum(si)
2. 所以,必须知道他在第i天的时候处在什么位置
3. dp[i][j] 表示第i天的时候处在j, dp[i+1][x] = dp[i][j] * (s[j] * l[x] + l[j] * s[x])
131 changes: 131 additions & 0 deletions src/codeforces/set1/set19/set197/set1970/e1/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package main

import (
"bufio"
"fmt"
"os"
)

func main() {
reader := bufio.NewReader(os.Stdin)

m, n := readTwoNums(reader)
s := readNNums(reader, m)
l := readNNums(reader, m)

res := solve(n, s, l)

fmt.Println(res)
}
func readString(reader *bufio.Reader) string {
s, _ := reader.ReadString('\n')
for i := 0; i < len(s); i++ {
if s[i] == '\n' || s[i] == '\r' {
return s[:i]
}
}
return s
}

func readInt(bytes []byte, from int, val *int) int {
i := from
sign := 1
if bytes[i] == '-' {
sign = -1
i++
}
tmp := 0
for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
tmp = tmp*10 + int(bytes[i]-'0')
i++
}
*val = tmp * sign
return i
}

func readNum(reader *bufio.Reader) (a int) {
bs, _ := reader.ReadBytes('\n')
readInt(bs, 0, &a)
return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
res := readNNums(reader, 2)
a, b = res[0], res[1]
return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
res := readNNums(reader, 3)
a, b, c = res[0], res[1], res[2]
return
}

func readNNums(reader *bufio.Reader, n int) []int {
res := make([]int, n)
x := 0
bs, _ := reader.ReadBytes('\n')
for i := 0; i < n; i++ {
for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
x++
}
x = readInt(bs, x, &res[i])
}
return res
}

const mod = 1e9 + 7

func add(a, b int) int {
a += b
if a >= mod {
a -= mod
}
return a
}

func sub(a, b int) int {
return add(a, mod-b)
}

func mul(a, b int) int {
return a * b % mod
}

func solve(n int, s []int, l []int) int {
m := len(s)

dp := make([]int, m)
// dp[i] = 在当前处于位置i时的状态数
dp[0] = 1
sp := mul(1, s[0])
lp := mul(1, l[0])

fp := make([]int, m)

for d := 0; d < n; d++ {
for i := 0; i < m; i++ {
// dp[i] = dp[j] * (((l[j] + s[j]) * s[i] + s[j] * (l[i] + s[i]))
tmp1 := mul(sp, add(l[i], s[i]))
tmp2 := mul(lp, s[i])
fp[i] = add(tmp1, tmp2)
}

sp = 0
lp = 0
for i := 0; i < m; i++ {
dp[i] = fp[i]
sp = add(sp, mul(dp[i], s[i]))
lp = add(lp, mul(dp[i], l[i]))
fp[i] = 0
}
}

var res int

for i := 0; i < m; i++ {
res = add(res, dp[i])
}

return res
}
19 changes: 19 additions & 0 deletions src/codeforces/set1/set19/set197/set1970/e1/solution_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import "testing"

func runSample(t *testing.T, n int, s []int, l []int, expect int) {
res := solve(n, s, l)

if res != expect {
t.Fatalf("Sample expect %d, but got %d", expect, res)
}
}

func TestSample1(t *testing.T) {
n := 2
s := []int{1, 0, 1}
l := []int{0, 1, 1}
expect := 18
runSample(t, n, s, l, expect)
}
163 changes: 163 additions & 0 deletions src/codeforces/set1/set19/set197/set1970/e2/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package main

import (
"bufio"
"fmt"
"os"
)

func main() {
reader := bufio.NewReader(os.Stdin)

m, n := readTwoNums(reader)
s := readNNums(reader, m)
l := readNNums(reader, m)

res := solve(n, s, l)

fmt.Println(res)
}
func readString(reader *bufio.Reader) string {
s, _ := reader.ReadString('\n')
for i := 0; i < len(s); i++ {
if s[i] == '\n' || s[i] == '\r' {
return s[:i]
}
}
return s
}

func readInt(bytes []byte, from int, val *int) int {
i := from
sign := 1
if bytes[i] == '-' {
sign = -1
i++
}
tmp := 0
for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
tmp = tmp*10 + int(bytes[i]-'0')
i++
}
*val = tmp * sign
return i
}

func readNum(reader *bufio.Reader) (a int) {
bs, _ := reader.ReadBytes('\n')
readInt(bs, 0, &a)
return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
res := readNNums(reader, 2)
a, b = res[0], res[1]
return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
res := readNNums(reader, 3)
a, b, c = res[0], res[1], res[2]
return
}

func readNNums(reader *bufio.Reader, n int) []int {
res := make([]int, n)
x := 0
bs, _ := reader.ReadBytes('\n')
for i := 0; i < n; i++ {
for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
x++
}
x = readInt(bs, x, &res[i])
}
return res
}

const mod = 1e9 + 7

func add(a, b int) int {
a += b
if a >= mod {
a -= mod
}
return a
}

func sub(a, b int) int {
return add(a, mod-b)
}

func mul(a, b int) int {
return a * b % mod
}

type Mat [][]int

func NewMat(n, m int) Mat {
res := make([][]int, n)
for i := 0; i < n; i++ {
res[i] = make([]int, m)
}
return res
}

func (this Mat) Mul(that Mat) Mat {
n := len(this)
res := NewMat(n, len(that[0]))

for i := 0; i < n; i++ {
for j := 0; j < len(that[0]); j++ {
for k := 0; k < len(that); k++ {
res[i][j] = add(res[i][j], mul(this[i][k], that[k][j]))
}
}
}
return res
}

func pow(m Mat, n int) Mat {
res := NewMat(len(m), len(m))
for i := 0; i < len(res); i++ {
res[i][i] = 1
}

for n > 0 {
if n&1 == 1 {
res = res.Mul(m)
}
m = m.Mul(m)
n >>= 1
}
return res
}

func solve(n int, s []int, l []int) int {
m := len(s)

mat := NewMat(m, m)

t := make([]int, m)
for i := 0; i < m; i++ {
t[i] = add(s[i], l[i])
}

for i := 0; i < m; i++ {
for j := 0; j < m; j++ {
mat[i][j] = sub(mul(t[i], t[j]), mul(l[i], l[j]))
}
}

res := pow(mat, n)

v := NewMat(m, 1)
v[0][0] = 1
v = res.Mul(v)

var ans int
for i := 0; i < m; i++ {
ans = add(ans, v[i][0])
}

return ans
}
19 changes: 19 additions & 0 deletions src/codeforces/set1/set19/set197/set1970/e2/solution_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import "testing"

func runSample(t *testing.T, n int, s []int, l []int, expect int) {
res := solve(n, s, l)

if res != expect {
t.Fatalf("Sample expect %d, but got %d", expect, res)
}
}

func TestSample1(t *testing.T) {
n := 2
s := []int{1, 0, 1}
l := []int{0, 1, 1}
expect := 18
runSample(t, n, s, l, expect)
}

0 comments on commit 9348480

Please sign in to comment.