{

很久以前就说过线段树的内容要写6篇了

没想到跨年了都 现在是总结的时候了

这里是以前的5篇

}

线段树总结 关键字

二分 将父亲区间均分设为儿子区间

切割 将查询区间切割为Log级别个的树上区间

概括 高效概括每个区间上的状况

合并 将不同的区间情况合并起来得到总区间的情况 

二分来源于线段树的定义

了解更多关于线段树的定义和基本性质 请移步这里

这是线段树之所以能够达到Log级别的本质原因

也是二进制思想的一个应用

还记得这一个问题吧

Pku 2777 http://poj.org/problem?id=2777

我在这里 也就是介绍线段树的第一篇里 把它做为例子

不知有没有发现 这个做法的最坏情况是O(Q*L)

这一篇以讨论这个问题为主线 总结线段树的思想

我们通过切割的思想来分析问题

我们引入一个东西叫混合颜色 查询到混合颜色就继续递归

那么 很容易想出一个数据 即所有的分支节点都是混合颜色 叶子染上黑白相间的颜色

那么查询就变成O(L)的了——必须遍历所有叶子节点

可以看到 这里线段树把查询区间切割成了L个区间 其实不如用一个线性表模拟

而实际上 我们发现树上的区间被查询区间完全包含了之后——

就不应当向下递归了 这样才是货真价实的Log2L个区间

 关于线段树切割区间与保证切割性质的Lazy-Tag的内容 请移步这里


那么我们为什么要记录混合颜色这种东西呢?

是因为我们不清楚 这个区间是什么情况 这就牵涉到概括的问题了

高效概括出每个区间的情况 并且支持高效合并运算

是我们最终完全解决这个问题的保障

我们讨论过树套树树状数组

为什么区间排名问题必须要在线段树的节点内加入一个平衡树?

因为我们非得知道这个区间里所有的数才能查询到某个数在这个区间的排名

为了高效维护这些数 我们就得用平衡树来组织

也就是用平衡树来概括区间信息

树状数组的本质是去除一部分节点的线段树 利用了某些合并运算的可减性

精简了某些区间 所以能够更高效的概括区间信息

回到这个问题 我们要概括包含某些颜色的区间的信息

并且支持高效的合并运算 我们可以看到 颜色最多才30种

利用一个32位长整形概括区间包含不包含各种颜色

合并运算就是Or运算 问题就可以解决了

比如一个区间含有1 2 3 5 号颜色 就存为10111=23

另一个区间含有1 3 4号颜色 就存为1101=11

合并两个区间就是含有1 2 3 4 5号颜色 即11 Or 23=10111 Or 1101=11111=31

就可以得到31这个结果 只要统计二进制中含有几个1就可以得到答案了

代码不难写 直接给出

Final

const max=200000;
var tt,n,t,q,x,y,z,i:longint;
l,r,c,d,ls,rs:array[1..max]of longint;
ch:char;
procedure down(x:longint);
begin
if d[x]>0
then begin
c[x]:=d[x];
if ls[x]<>0 then d[ls[x]]:=d[x];
if rs[x]<>0 then d[rs[x]]:=d[x];
d[x]:=0;
end;
end;
procedure update(x:longint);
begin
down(ls[x]); down(rs[x]);
c[x]:=c[ls[x]] or c[rs[x]];
end;
procedure build(a,b:longint);
var x,mid:longint;
begin
inc(tt); x:=tt;
c[x]:=1; d[x]:=0;
l[x]:=a; r[x]:=b;
if b-a>1
then begin
mid:=(a+b)shr 1;
ls[x]:=tt+1; build(a,mid);
rs[x]:=tt+1; build(mid,b);
end;
end;
procedure cover(x,a,b,c:longint);
var mid:longint;
begin
down(x);
if (a<=l[x])and(r[x]<=b)
then d[x]:=c
else begin
mid:=(l[x]+r[x])shr 1;
if a<mid then cover(ls[x],a,b,c);
if b>mid then cover(rs[x],a,b,c);
update(x);
end;
end;
function count(x,a,b:longint):longint;
var mid:longint;
begin
down(x);
if (a<=l[x])and(r[x]<=b)
then count:=c[x]
else begin
count:=0;
mid:=(l[x]+r[x])shr 1;
if a<mid then count:=count or count(ls[x],a,b);
if b>mid then count:=count or count(rs[x],a,b);
end;
end;
function calcu(x:longint):longint;
begin
calcu:=0;
while x>0 do
begin
calcu:=calcu+x and 1;
x:=x shr 1;
end;
end;
begin
assign(input,'Count.in'); reset(input);
assign(output,'Count.out'); rewrite(output);
readln(n,t,q);
build(0,n);
for i:=1 to q do
begin
read(ch,x,y);
if x>y
then begin
z:=x; x:=y; y:=z;
end;
if ch='P'
then writeln(calcu(count(1,x-1,y)))
else begin
read(z);
cover(1,x-1,y,1 shl (z-1));
end;
readln;
end;
close(input); close(output);
end.

关于线段树的介绍 到此告一段落

以后如果还有好玩的经典的 线段树问题 还会新写

谢谢阅读 如有不足欢迎指正!

转载于:https://www.cnblogs.com/Booble/archive/2011/01/02/1924125.html

[Pku 2777] 线段树(六) {总结}相关推荐

  1. poj pku 2528 线段树的基础应用

    郁闷了一上午的题目,一直都是WA,找了老半天错,想了很多测试数据还是WA.就连骑单车回家的路上还在想这题.悲剧呀... 做完这个题目才明白线段树不同于其他算法,它只是一种思想,在实际应用中是要根据题意 ...

  2. poj 2777(线段树+区间染色)

    解题思路:这道题利用了线段树+位运算的思想,由于颜色的种类只有30种,所以int可以存下来,所以我们在线段树的节点里面加上status的状态信息,表示这段区间内的颜色信息,而且我们可以知道,父节点的s ...

  3. POJ 2777 线段树

    一道线段树.lazy标记+位运算--(第一次写这个什么lazy标记,抄了一发题解) 我们发现:"或"操作在这里用正合适. 原题请戳这里 // by Sirius_Ren #incl ...

  4. poj 2777 Count Color(线段树区区+染色问题)

    题目链接:  poj 2777 Count Color 题目大意:  给出一块长度为n的板,区间范围[1,n],和m种染料 k次操作,C  a  b  c 把区间[a,b]涂为c色,P  a  b 查 ...

  5. poj 2777 AND hdu 5316 线段树

    区间染色问题,用线段树可以解决.颜色总类不多,故考虑用二进制数的每一位表示一种颜色,然后父节点的颜色就是孩子节点颜色"或"起来,加上lazy标记,轻松AC. poj 2777: 1 ...

  6. 小学六年级学生写的 “线段树”解析,厉害了!

    作者 | 王乙堃 来源 | 程序员小灰 线段树是一个复杂的数据结构,比较难理解,也比较难解释清楚.在我将这个数据结构反复学习了五遍的时候,我终于有了信心写出这篇介绍线段树的文章.希望大家能够掌握这种数 ...

  7. POJ 2777 Count Color (线段树区间修改 + 状态压缩)

    题目链接:POJ 2777 Count Color [题目大意] 给你 n 块板子, 编号1--n , 板子的颜色最多30种, 初始时  板子的颜色都是 1: 有两种操作 1 .把给定区间的板子染成一 ...

  8. 线段树区间染色 浮水法 学习小记 Poj 2777 + Poj 2528

    复习过的东西必须时常拿来练练,虽说都是水题.... Poj 2777 典型的区间染色问题,貌似我的写法为了不数组越界必须多开一倍的数组空间.....还没有想到解决方法,有机会参考一下别人的写法. Po ...

  9. 线段树专辑——pku 2886 Who Gets the Most Candies?

    http://poj.org/problem?id=2886 恩,分糖果,快乐的童年啊! 题目意思大概n个小孩围成一个圈,每个小孩手里有张卡片,记录着一个数字.开始从第k个孩子,该孩子离开圈子,然后告 ...

  10. 线段树专辑 —— pku 2482 Stars in Your Window

    http://poj.org/problem?id=2482 A了这题后,我就在想,是不是ACMER都找不到女朋友..... 这题看似很新颖,其实就是求线段树区间最值.所谓区间最值,其实就是和RMQ差 ...

最新文章

  1. linux进程状态d状态,Linux下进程的状态
  2. JS里在光标位置插入字符
  3. 633. Sum of Square Numbers
  4. 【Python】青少年蓝桥杯_每日一题_4.03_求偶数
  5. where to find fundings as an MPhil student?
  6. dw替换多个html标签,DW查找替换的技巧
  7. java queue 实现类 区别_Java集合11 (Queue)
  8. 到底是无线最难?还是核心网最难?
  9. 先进数据系统实验室(Advanced Data Systems Laboratory, ADSL)
  10. 多目标跟踪 综述(三)
  11. SonyZ2国行版L50t使用谷歌play服务安装谷歌四件套
  12. 做H5页面用什么软件比较好?
  13. 计算机关机时间设置方法,win7 设置定时关机方法_win7 如何设置关机时间-win7之家...
  14. android 调用webservice实现手机号码归属地查询
  15. html圆圈男女,html圆形导航导航
  16. 什么是Tableau(BI工具)
  17. 制作自动添加IE信任站点运行文件
  18. WPS 关闭广告,热点 解决方案
  19. registrar计算机词汇,HR常用短语英语词汇表(转载)
  20. 22-0002 天猫店铺搜索页面分析

热门文章

  1. Dos window下运行java程序
  2. extjs fileuploadfield default value
  3. excel查找和替换
  4. dev gridcontrol 单选框效果
  5. 查看sqlserver2008数据库服务器实例名称
  6. Windows 7 - 使用批处理脚本模拟Windows XP中的msbackup备份程序
  7. 分享一个 pycharm 专业版的永久使用方法
  8. property自己实现
  9. 凸优化第八章几何问题 8.5 中心
  10. todo elk搭建日志系统