Forgot password?
 Create new account
Search
View: 17|Reply: 7

线段树与代数

[Copy link]

3152

Threads

8383

Posts

610K

Credits

Credits
65402
QQ

Show all posts

hbghlyj Post time 2023-7-14 08:56 |Read mode
来自资料《线段树与代数》:

代数学在算法与数据结构的应用,已经被很多人了解,但是据我所知还没有比较系统的叙述。
之前有群友推荐了《Haskellでわかる群論の代数的構造》但是我不懂日语。
那个ppt是我在年级里面讲的,或许可以展示一下思路。
《segment_tree_lecture》是在南美的一个icpc培训活动中一位俄罗斯人的讲稿,是我目前见到的描述比较清楚的讲稿。(虽然缺乏清晰的资料,但是很多人都在实际使用)
$type segment_tree_lecture.pdf (138.46 KB, Downloads: 1)
《The Categories of Graphs》可能是描述算法与数据结构中的代数的比较有力的语言的例子。
$type The Categories of Graphs.pdf (903.66 KB, Downloads: 1)

3152

Threads

8383

Posts

610K

Credits

Credits
65402
QQ

Show all posts

 Author| hbghlyj Post time 2023-7-14 08:58
本帖最后由 hbghlyj 于 2023-7-14 10:08 编辑

比如说现在有 西园一舍 到 西园一千舍,每个大舍有一千栋楼,每栋楼有一千个寝室。​
我们希望时刻统计学生的用水用电数据。​
而数据每秒都在更新。
    具体来说,我们希望统计:​
    哪个大舍用水最多        (会不会是水管漏水了?​
    哪个楼用水最多        (楼上的水管漏水了?​
    对于每个大舍,哪一个小寝用水最多        (哪个人浪费的水流到脑子里了?​
我们希望很快速的查询这些信息。比如说,鼠标一点就能跳出来实时的数据。​
我们要查询某段的和,我们要查询某段的最大值。即使是计算机,也不是那么快就能处理10^9的数据(点一下就出来)​
    Naïve 的做法,就是每秒更新后,就一个一个的算​
    容我展示一下

每秒钟用水用电的数据都在更新​
每秒钟要修改1000000000个变量的值​
我们希望能够随便查询任意宿舍到任意宿舍的用水量总和​
也就是说,枚举左右区间​
那么为了查询的时候更方便快捷,我们愿意事先把这些区间和事先准备好​
一共也就是1000000000000000000个数字​
每一秒都在更新…………每一秒都要算…………上一秒的数据还没算完下一秒又来了,难道我们不得不寅吃卯粮杀鸡取卵了吗QAQ​

数据更新​

大家可能对我上一页的说法不屑一顾​
因为我们没必要一直算这么多啊!台上这位明显是哗众取宠纸上谈兵不值一提!​
是的!我们有更好的方法!

3152

Threads

8383

Posts

610K

Credits

Credits
65402
QQ

Show all posts

 Author| hbghlyj Post time 2023-7-14 09:07
本帖最后由 hbghlyj 于 2023-7-14 10:37 编辑

大概讲一下,反正你们也不会听,哼~
  • 线段树、树状数组能实现log级修改与查询
  • 具体来说,树状数组这样实现:







横条表示:储存了横条所覆盖的区间的总和​
绿色的棒棒糖表示:要把对应区间的总和储存在哪个位置​
注意到与二进制的关系了吗?

3152

Threads

8383

Posts

610K

Credits

Credits
65402
QQ

Show all posts

 Author| hbghlyj Post time 2023-7-14 10:36
本帖最后由 hbghlyj 于 2023-7-14 11:28 编辑

数据查询

2
3
4
5
1
2
3
2
1
6
2
2
1
3
1
4
2
5
3
7
14
22










3152

Threads

8383

Posts

610K

Credits

Credits
65402
QQ

Show all posts

 Author| hbghlyj Post time 2023-7-14 11:30
本帖最后由 hbghlyj 于 2023-7-14 11:40 编辑

数据更新 和 "Lazy Tag"

+1










3152

Threads

8383

Posts

610K

Credits

Credits
65402
QQ

Show all posts

 Author| hbghlyj Post time 2023-7-14 11:42
本帖最后由 hbghlyj 于 2023-7-14 12:23 编辑

那线段树又是什么?

线段树和树状数组本来是能讲两个星期的课,大家大概听一耳朵就完啦~​

n + n/2 + n/4 + …… = 2*n​

Untitled.png
上面的横条会储存下面对应的两个横条之和​
可以看出,抽象的意义上,树状数组是线段树的真子集​
所以,树状数组上能实现的,线段树上一定也能实现,毕竟花费了两倍的存储空间嘛。​

3152

Threads

8383

Posts

610K

Credits

Credits
65402
QQ

Show all posts

 Author| hbghlyj Post time 2023-7-14 12:26
本帖最后由 hbghlyj 于 2023-7-14 12:43 编辑

那么,线段树能做什么特别的事情?​

画风突变

你以为你以为的就是我说的“加法”“求和”吗?​

实际上我刚才说的树状数组加法,指的是交换群​
设<$G,*$>是一个群,​
若对任意\(​a,b∈G\), \((a*b)*(a*b)=(a*a)*(b*b)​\), 则\(G\)是交换群​
实际上我刚才说的 线段树 求和,指的是幺半群​
考虑 \(S\) 上的二元运算 \(*​\)
若 存在单位元、满足结合律,则称为幺半群​
(同时,如果还有\(S\)上的二元运算\(+\),且\(*\)对\(+\)满足右分配律,还可以使用lazytag​

具体来说,拿一些不常见的运算举个例子​

定义 $a*b$ 为 $\max(a,b)​$
显然 $a * b = b * a$ 满足交换律,​
但由于 $*$ 对加法​不满足 $a * ( b + c ) = ( a * b ) + ( a * c )$​ [考虑 $a=3, b=2, c=2​$.]
所以不能使用lazytag​
对于单独的加法,单独的求$\max$,都可以使用树状数组,两者加在一起同时维护的话,不是不能用,但是效率会差一些​

具体来说,拿一些不常见的运算举个例子​

把“刷墙”看作一种运算 \(*\)​ \[红色 * 蓝色 = 蓝色 ​\] 把蓝色的油漆涂在了(已经干了的)红色油漆上,就变成了蓝色​ \[(红色 * 蓝色)* 白色 = 白色​\] 在上面的基础上,又把墙刷白了​ \[(红色 * 蓝色)* 白色 = 红色 * (蓝色* 白色)= 红色 * 白色 ​\] 很难说上式有什么物理意义,但在数学上是成立的​ “刷墙”运算满足结合律,可以使用线段树。
但显然“刷墙”运算不满足交换律,不能使用树状数组。​

西园一舍 到 西园一千舍,每个大舍有一千栋楼,每栋楼有一千个寝室​
水电费都是数字,我们要进行的操作也只是查询加法、最大值等​

3152

Threads

8383

Posts

610K

Credits

Credits
65402
QQ

Show all posts

 Author| hbghlyj Post time 2023-7-14 12:34
懂了很多数据结构,却依然过不好这一生​
    如果我们把问题换一下:nico 和 maki 有一千台手机,每个手机上有一千个外卖软件,每个外卖软件上有一千个优惠券。​
    我们希望以最便宜的方式购买足够西园七舍的人吃的外卖​
    又比如: nico 和 maki 有一千台手机,每个手机上有一千张不同运营商的手机卡,每个运营商提供了一千种流量套餐​
    我们希望用最便宜的价格购买足够下载上述外卖软件的流量包​

    这些问题可能就很难解决了,因为优惠券、流量包所组成的代数系统的代数性质非常差​
    具体来说,可能优惠券a与优惠券c互斥,而与优惠券b每台手机每个注册手机号以及每个收货手机号仅可以共存一次(仅限指定商家、收货地点仅限指定地区、最终解释权归兲困外卖所有)​
    流量也是这样,经常是 10 块钱 50 M ,20 块钱 500 M , 30块钱 5000 M(部分流量仅限指定地区、指定软件、或者指定时间使用,最终解释权归中国由言所有)​

    这就很难受了,因为这些东西在时间上不守恒、空间上不守恒,甚至不能保证这次买后下次还是一样的价格。​
    我们考虑把外卖优惠券的叠加 作为二元运算 *​
    a * b = b * a 吗?​
    (a*b)*c=a*(b*c)吗?​
    可能要确认一下 a 是商家优惠还是兲困外卖的红包。可能a是八折券,b是付款时的折扣。​
    还要看看自己是在哪里点的,手机号之前有没有注册过账号,收货地点在哪里。​

感谢大家~​
    Email:selenfall#foxmail。com​
    计拔 lulu ​

手机版|悠闲数学娱乐论坛(第3版)

2025-3-7 00:59 GMT+8

Powered by Discuz!

× Quick Reply To Top Return to the list