[go刷题模板] SortedList/简单名次树

文章介绍了如何使用Go语言构建一个简单的SortedList数据结构,用于查询元素排名和数量。虽然不支持删除操作,但提供了查询效率为O(log2n)的bisect_left方法。此外,文章还对比了Go实现与树状数组在处理相同数据量时的性能差异,并给出了完整的代码示例。
摘要由CSDN通过智能技术生成

一、 算法&数据结构

1. 描述

py的SortedList超好用,但是代码很长,这里用简单的代码搞一个,但是不支持删除。
  • 另外第k大也可以搞,有空再补。
  • 不过实测同一道题2e5的数据量,go的SortedList性能比用树状数组差很多:1372ms -> 420ms

2. 复杂度分析

  1. 查询query, O(log2n)
  2. 更新update,O(log2n)

3. 常见应用

4. 常用优化

二、 模板代码

1. 查询v在数据中的名次/有多少数小于v/bisect_left(v)

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"sort"
)

// SortedList 1372ms
func solve(in io.Reader, out io.Writer) {
	var n int
	Fscan(in, &n)
	type seg struct{ i, l, r int }
	a := make([]seg, n)
	for i := 0; i < n; i++ {
		Fscan(in, &a[i].l, &a[i].r)
		a[i].i = i
	}
	sort.Slice(a, func(i, j int) bool { return a[i].r < a[j].r })
	ans := make([]int, n)
	p := NewSortedList()
	for _, s := range a {
		l, i := s.l, s.i
		//ans[i] = len(p) - p.BisectLeft(l)
		ans[i] = p.Len() - p.BisectLeft(l)
		p.Add(l)
	}

	for _, v := range ans {
		Fprintln(out, v)
	}
}

func run(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()
	solve(in, out)
}

func main() { run(os.Stdin, os.Stdout) }

type SortedList struct {
	Small []int
	Large []int
}

func NewSortedList() SortedList {
	var small []int
	var large []int
	return SortedList{small, large}
}

func (u *SortedList) Add(v int) {
	if len(u.Small) > 6700 {
		u.Large = append(u.Large, u.Small...)
		u.Small = []int{}
		sort.Ints(u.Large)
	}
	if len(u.Small) == 0 || u.Small[len(u.Small)-1] <= v {
		u.Small = append(u.Small, v)
	} else if u.Small[0] >= v {
		u.Small = append([]int{v}, u.Small...)
	} else {
		p := sort.Search(len(u.Small), func(i int) bool { return u.Small[i] >= v })
		t := append([]int{}, u.Small[p:]...) // 实现insert 需要保存临时变量
		u.Small = append(u.Small[:p], v)
		u.Small = append(u.Small, t...)
		//u.Small = append(u.Small[:p], append([]int{v}, u.Small[p:]...)...)
	}
}

func (u SortedList) BisectLeft(v int) int {
	return sort.Search(len(u.Small), func(i int) bool { return u.Small[i] >= v }) + sort.Search(len(u.Large), func(i int) bool { return u.Large[i] >= v })
}

func (u SortedList) Len() int {
	return len(u.Small) + len(u.Large)
}

三、其他

四、更多例题

五、参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值