Skip to content

Commit

Permalink
aaa
Browse files Browse the repository at this point in the history
  • Loading branch information
WangSenyuan committed Mar 22, 2024
1 parent 57204dd commit 6f877af
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/codeforces/set0/set1/set100/set140/set145/e/problem.md
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 src/codeforces/set0/set1/set100/set140/set145/e/solution.go
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 src/codeforces/set0/set1/set100/set140/set145/e/solution_test.go
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)
}

0 comments on commit 6f877af

Please sign in to comment.