-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
WangSenyuan
committed
Mar 22, 2024
1 parent
57204dd
commit 6f877af
Showing
3 changed files
with
279 additions
and
0 deletions.
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
src/codeforces/set0/set1/set100/set140/set145/e/problem.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Petya loves lucky numbers very much. Everybody knows that lucky numbers are positive integers whose decimal record | ||
contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not. | ||
|
||
Petya brought home string s with the length of n. The string only consists of lucky digits. The digits are numbered from | ||
the left to the right starting with 1. Now Petya should execute m queries of the following form: | ||
|
||
switch l r — "switch" digits (i.e. replace them with their opposites) at all positions with indexes from l to r, | ||
inclusive: each digit 4 is replaced with 7 and each digit 7 is replaced with 4 (1 ≤ l ≤ r ≤ n); | ||
count — find and print on the screen the length of the longest non-decreasing subsequence of string s. | ||
Subsequence of a string s is a string that can be obtained from s by removing zero or more of its elements. A string is | ||
called non-decreasing if each successive digit is not less than the previous one. | ||
|
||
Help Petya process the requests. | ||
|
||
### ideas | ||
|
||
1. 将4看作0,7看作1,就变成了0/1字符串 | ||
2. 不考虑switch的情况,如何count呢? | ||
3. 正常情况下,应该是一个位置i的前面的所有的0+后面所有的1(它自己的值不重要) | ||
4. 但如何计算一段[l..r]内的呢? | ||
5. 假设每段上维护了以下值value (最大值), cnt[0]/cnt[1] | ||
6. 那么value(l...r) = max(value of first half + 右边cnt[1], 左边cnt[0] + value of second half) | ||
7. 但是翻转的时候, value怎么变化呢? |
200 changes: 200 additions & 0 deletions
200
src/codeforces/set0/set1/set100/set140/set145/e/solution.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
func main() { | ||
reader := bufio.NewReader(os.Stdin) | ||
|
||
n, m := readTwoNums(reader) | ||
s := readString(reader)[:n] | ||
|
||
queries := make([]string, m) | ||
for i := 0; i < m; i++ { | ||
queries[i] = readString(reader) | ||
} | ||
|
||
res := solve(s, queries) | ||
|
||
var buf bytes.Buffer | ||
|
||
for _, x := range res { | ||
buf.WriteString(fmt.Sprintf("%d\n", x)) | ||
} | ||
|
||
fmt.Print(buf.String()) | ||
} | ||
|
||
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 | ||
} | ||
|
||
func solve(s string, queries []string) []int { | ||
tr := Build(s) | ||
|
||
var ans []int | ||
|
||
for _, cur := range queries { | ||
if cur == "count" { | ||
ans = append(ans, tr.value[0]) | ||
} else { | ||
var l, r int | ||
pos := readInt([]byte(cur), len("switch")+1, &l) | ||
readInt([]byte(cur), pos+1, &r) | ||
l-- | ||
r-- | ||
tr.Flip(l, r, len(s)) | ||
} | ||
} | ||
|
||
return ans | ||
} | ||
|
||
type Node struct { | ||
flag bool // 是否翻转 | ||
value [2]int // 0最长递增序列, 1最长递减序列 | ||
cnt [2]int // 0/1的数量 | ||
left *Node | ||
right *Node | ||
} | ||
|
||
func (node *Node) pull() { | ||
node.value[0] = max(node.left.value[0]+node.right.cnt[1], node.left.cnt[0]+node.right.value[0]) | ||
node.value[1] = max(node.left.value[1]+node.right.cnt[0], node.left.cnt[1]+node.right.value[1]) | ||
|
||
node.cnt[0] = node.left.cnt[0] + node.right.cnt[0] | ||
node.cnt[1] = node.left.cnt[1] + node.right.cnt[1] | ||
} | ||
|
||
func max(a, b int) int { | ||
if a >= b { | ||
return a | ||
} | ||
return b | ||
} | ||
|
||
func (node *Node) push() { | ||
if node.flag { | ||
if node.left != nil { | ||
node.left.flip() | ||
node.right.flip() | ||
} | ||
node.flag = false | ||
} | ||
} | ||
|
||
func (node *Node) flip() { | ||
node.value[0], node.value[1] = node.value[1], node.value[0] | ||
node.cnt[0], node.cnt[1] = node.cnt[1], node.cnt[0] | ||
node.flag = !node.flag | ||
} | ||
|
||
func Build(s string) *Node { | ||
|
||
var loop func(l int, r int) *Node | ||
|
||
loop = func(l int, r int) *Node { | ||
node := new(Node) | ||
if l == r { | ||
x := checkValue(s[l]) | ||
node.cnt[x]++ | ||
node.value[0] = 1 | ||
node.value[1] = 1 | ||
return node | ||
} | ||
mid := (l + r) / 2 | ||
node.left = loop(l, mid) | ||
node.right = loop(mid+1, r) | ||
node.pull() | ||
return node | ||
} | ||
|
||
return loop(0, len(s)-1) | ||
} | ||
|
||
func checkValue(x byte) int { | ||
if x == '4' { | ||
return 0 | ||
} | ||
return 1 | ||
} | ||
|
||
func (root *Node) Flip(L int, R int, n int) { | ||
|
||
var loop func(node *Node, l int, r int) | ||
loop = func(node *Node, l int, r int) { | ||
node.push() | ||
|
||
if r < L || R < l { | ||
// out of bounds | ||
return | ||
} | ||
if L <= l && r <= R { | ||
node.flip() | ||
return | ||
} | ||
mid := (l + r) / 2 | ||
loop(node.left, l, mid) | ||
loop(node.right, mid+1, r) | ||
node.pull() | ||
} | ||
|
||
loop(root, 0, n-1) | ||
} |
56 changes: 56 additions & 0 deletions
56
src/codeforces/set0/set1/set100/set140/set145/e/solution_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package main | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func runSample(t *testing.T, s string, queries []string, expect []int) { | ||
res := solve(s, queries) | ||
|
||
if !reflect.DeepEqual(res, expect) { | ||
t.Fatalf("Sample expect %v, but got %v", expect, res) | ||
} | ||
} | ||
|
||
func TestSample1(t *testing.T) { | ||
s := "47" | ||
queries := []string{ | ||
"count", | ||
"switch 1 2", | ||
"count", | ||
} | ||
expect := []int{2, 1} | ||
runSample(t, s, queries, expect) | ||
} | ||
|
||
func TestSample2(t *testing.T) { | ||
s := "747" | ||
queries := []string{ | ||
"count", | ||
"switch 1 1", | ||
"count", | ||
"switch 1 3", | ||
"count", | ||
} | ||
expect := []int{2, 3, 2} | ||
runSample(t, s, queries, expect) | ||
} | ||
|
||
func TestSample3(t *testing.T) { | ||
s := "7474747" | ||
queries := []string{ | ||
"count", | ||
"count", | ||
"switch 1 7", | ||
"count", | ||
"switch 1 1", | ||
"switch 3 3", | ||
"switch 5 5", | ||
"count", | ||
"switch 1 7", | ||
"count", | ||
} | ||
expect := []int{4, 4, 4, 6, 7} | ||
runSample(t, s, queries, expect) | ||
} |