dengxinyi 6 роки тому
батько
коміт
4f527954a1

+ 44 - 1
2008/1C/C/main.go

@@ -6,10 +6,53 @@ import (
 	"os"
 )
 
+// MOD ...
+const MOD = 1000000007
+
 func countIncreasing(scanner *bufio.Scanner) []int {
 	caseCnt := ReadInt(scanner)
 	answer := make([]int, caseCnt)
 	for cid := 0; cid < caseCnt; cid++ {
+		println("Case", cid+1, "/", caseCnt)
+		params := ReadInts(scanner)
+		n, m, X, Y, Z := params[0], params[1], params[2], params[3], params[4]
+		A := make([]int, m)
+		limits := make([]int, n)
+		for i := 0; i < n; i++ {
+			if i < m {
+				A[i] = ReadInt(scanner)
+			}
+			limits[i] = A[i%m]
+			A[i%m] = (X*A[i%m] + Y*(i+1)) % Z
+		} // To generate input array 'limits'
+		st := NewSegmentTree(limits)
+		dp := make([]int, n+1)
+		dp[0] = 1
+		for i := 1; i <= n; i++ {
+			dp[i]++
+			// *********************************
+			// *     Segment tree solution     *
+			// *********************************
+			for j := st.NextGreater(limits[i-1], i) + 1; j != 0; j = st.NextGreater(limits[i-1], j) + 1 {
+				dp[j] += dp[i]
+				dp[j] %= MOD
+			}
+			// *********************************
+			// *       Original solution       *
+			// *********************************
+			// for j := i + 1; j <= n; j++ { // It is too slow to search between i+1 and n for big case
+			// 	if limits[i-1] < limits[j-1] {
+			// 		dp[j] += dp[i]
+			// 		dp[j] %= MOD
+			// 	}
+			// }
+			// *********************************
+			// Both are to slow for solving the big problem set.
+		}
+		for i := 1; i <= n; i++ {
+			answer[cid] += dp[i]
+		}
+		answer[cid] %= MOD
 	}
 	return answer
 }
@@ -23,7 +66,7 @@ func main() {
 		test
 	)
 
-	fileType := test
+	fileType := small
 
 	fin, _ := os.Open(inputFiles[fileType])
 	defer fin.Close()

+ 20 - 0
2008/1C/C/result-large.out

@@ -0,0 +1,20 @@
+Case #1: 0
+Case #2: 0
+Case #3: 0
+Case #4: 0
+Case #5: 0
+Case #6: 0
+Case #7: 0
+Case #8: 0
+Case #9: 0
+Case #10: 0
+Case #11: 0
+Case #12: 0
+Case #13: 0
+Case #14: 0
+Case #15: 0
+Case #16: 0
+Case #17: 0
+Case #18: 0
+Case #19: 0
+Case #20: 0

+ 20 - 0
2008/1C/C/result-small.out

@@ -0,0 +1,20 @@
+Case #1: 792175524
+Case #2: 423939827
+Case #3: 387647936
+Case #4: 166445575
+Case #5: 882703538
+Case #6: 847359953
+Case #7: 484507583
+Case #8: 250869684
+Case #9: 1
+Case #10: 709192742
+Case #11: 513
+Case #12: 240536891
+Case #13: 349436385
+Case #14: 870681372
+Case #15: 20391557
+Case #16: 44377583
+Case #17: 239694902
+Case #18: 478388251
+Case #19: 199934414
+Case #20: 710104286

+ 46 - 0
2008/1C/C/segment_tree.go

@@ -0,0 +1,46 @@
+package main
+
+// SegmentTree ...
+type SegmentTree []int
+
+// NewSegmentTree ...
+func NewSegmentTree(a []int) (st SegmentTree) {
+	n := len(a)
+	st = make([]int, 2*n)
+	copy(st[n:], a)
+	for i := n - 1; 0 < i; i-- {
+		st[i] = maxInt(st[2*i], st[2*i+1])
+	}
+	return
+}
+
+// NextGreater ...
+func (st SegmentTree) NextGreater(val, i int) int {
+	n := len(st) / 2
+	beg, end := i+n, 2*n
+	if end <= beg {
+		return -1
+	}
+	for ; st[beg] <= val && beg < end; beg, end = beg/2, end/2 {
+		if beg%2 == 1 {
+			beg++
+		}
+		if end%2 == 1 {
+			end--
+		}
+	}
+	if st[beg] <= val {
+		return -1
+	}
+	for beg < n {
+		if val < st[2*beg] {
+			beg = 2 * beg
+		} else {
+			beg = 2*beg + 1
+		}
+	}
+	if beg-n < i {
+		return -1
+	}
+	return beg - n
+}

+ 2 - 0
2008/1C/C/test.out

@@ -0,0 +1,2 @@
+Case #1: 15
+Case #2: 13

+ 7 - 0
2008/1C/C/utils.go

@@ -61,3 +61,10 @@ func ReadInt64s(s *bufio.Scanner) []int64 {
 	}
 	return nums
 }
+
+func maxInt(x, y int) int {
+	if y < x {
+		return x
+	}
+	return y
+}