数据结构(下)

1.树套树

(1)树状数组套树状数组

前置:

树状数组如何支持区间加以及区间查询

维护一个差分数组,用来求一个位置的值,我们只需要把前缀和看作是一个矩形,

减去两数插值产生的贡献即可

1.P4514 上帝造题的七分钟

题意:支持矩形加某个数和矩形查询值。

考虑将每个点差分,当我们要将\((a,b),(x,y)\)范围内的矩阵加1时,其实就是:

\(A(a,b)+1\)

\(A(x,b+1)-1\)

\(A(a,y+1)-1\)

\(A(x+1,y+1)+1\)

于是乎,前缀和:

\[\sum_{i=a}^x\sum_{j=b}^yA(i,j)*(x-i+1)*(y-j+1)\]

\[\sum_{i=a}^x\sum_{j=b}^yA(i,j)*(x*y+1)+A(i,j)*i*j-A(i,j)*i*(y+1)-A(i,j)*j*(x+1)\]

维护\(A(i,j)*i*j,A(i,j)*i,A(i,j)*j,A(i,j)\)即可

(2).权值线段树套区间线段树

1.P3332 [ZJOI2013]K大数查询

题意:

1 a b c:表示在第a个位置到第b个位置,每个位置加上一个数c

2 a b c:表示询问从第a个位置到第b个位置,第C大的数是多少

直接上。。。

(3).树状数组套主席树

我们发现单个的主席树就类似于我们单个的一个前缀和。当我们需对一个点进行修

改,并且求值是,我们考虑用树状数组维护区间关系,使每一次的修改次数下降到

\(O(log^2n)\),但每次查询也变成了这样的复杂度。

1.P2617 Dynamic Rankings 裸题
2.动态逆序对
3.P4175 [CTSC2008]网络管理

题意:在一棵树上维护一条链上的第k大的值,并支持修改。

题解:直接树套树再套一个树剖,优秀\(O(nlog^3n)\)

(4).线段树套平衡树

1.P3380 【模板】二逼平衡树(树套树)

某巨巨说并没有什么用,这个的话我其实使自己\(yy\)出来的\(O(log^3n)\)的做法,

但蒟蒻自带大常数,就是过不了。

2.点分治

点分治的复杂度正确在于每一次都求了一边重心,维护了树的高度,总复杂度是

\(O(nlog n)\)的

1.P3806 【模板】点分治1

题解:板子滚粗

2.P4149 [IOI2011]Race

题解:多维护一个边的数量

3.P2634 [国家集训队]聪聪可可

题解:板子滚粗

3.动态点分治

动态点分治就是支持修改对吧。。。。。。

然后我们知道本来点分治就是不断的找重心,于是根据此我们可以建出一棵点分

树,非常的优秀。而我们知道其实每次点分治无非就是每次重心的答案总和。我

们直接记录每个重心的答案即可。建出来的点分树复杂度还是非常有保障的。

动态点分治还是很给人启示的。

1.P3345 [ZJOI2015]幻想乡战略游戏

题意:一棵树上,有边权,点权。支持点权修改,要求找出一个点,使所有点的

权值*到这个点的距离和最小。

题解:

1.这道题的优美性质就是要找到这棵树的重心。

2.这道题如果直接找重心满足$2\times sumd_v>sumd_u $则向v走。

3.我们要统计的是所有重心到这个点的距离*权值。点分树可以做到。类似于:

ll count(int x){
    ll res = 0 ;
    res += sumval[x] ;
    for(int i = x ; Hfa[i] ; i = Hfa[i] ){
        ll fr = Distance( x , Hfa[i] ) ;
        res += ( sumval[Hfa[i]] - sumf[i] ) ;
        res += 1ll * ( sumg[Hfa[i]] - sumg[i] ) * fr ;
    }
    return res ;
}
ll query(int x){
    ll tmp = count( x ) ;
    for(int i = Fire[x] ; i ; i = Nex[i] ){
        int v = To[i] ;
        if( count( v ) < tmp ) return query( near[i] ) ;
    }
    return tmp ;
}
2.P3241 [HNOI2015]开店

这道题其实和上面的套路一样,点分树建一波,vector记一波。

3.P3676 小清新数据结构题

就是一道神题。

我们用\(S_i\)表示\(i\)的子树

这里你会发现\(\sum_{i=1}^nS_i^2\)是个不太好处理而且没有什么非常优美的性质

我们暂时先不考虑修改,让我们看一下换根回产生什么样的影响:

假如这棵树是这样的。现在以\(5\)号点为根,现在打算以\(1\)号点为根

发现只有路径\(1-5\)的点上的子树大小会变。于是你会发现一个优美而又可怕的结

论:

\[\sum_{i=1}^nS_i(Sum-S_i)\]

是个定值。设这个定值为\(W\)

那么答案就是

\[ans=Sum\sum_{i=1}^nS_i-W\]

然而

\[\sum_{i=1}^nS_i=\sum_{i=1}dep_ivali\]

这个点分树可以直接胜任

我们开始考虑单点的修改。

对于任何两个点,他们的乘积所产生的贡献既为他们刚好没被分在同一子树内。

这样的情况就有\(dis(i,j)\)次

所以

\[\sum_{i=1}^nS_i(Sum-Si)=\sum_{i=1}^n\sum_{j=1}^ndis(i,j)val_ival_j\]

对于单点修改:

\[W_{new}=add*\sum_{j=1}^ndis(i,j)*val_j\]

这个的话,点分树还是可以胜任

写法和上面的大同小异

4.捉迷藏 P2056 [ZJOI2007]捉迷藏

不是我说难码,可以学习的就是那个堆的使用

struct node{
    priority_queue<int> A , B ;
    void insert(int x){
        A.push(x) ;
    }
    void dele(int x){
        if( A.top() == x ) A.pop() ;
        else B.push(x) ;
    }
    int Top(){
        while( !A.empty() && !B.empty() && A.top() == B.top() ) A.pop() , B.pop() ;
        if( A.empty() ) return -inf ;
        else return A.top() ;
    }
    int nex_top(){
        int rt = Top() ;
        if( rt == -inf ) return -inf ;
        A.pop() ; int nexrt = Top() ;
        A.push( rt ) ;
        return nexrt ;
    }
}ans , tofa[N] , stree[N] ;

4.LCT

(1)链信息:

1.P1501 [国家集训队]Tree II
2.P2147 [SDOI2008]洞穴勘测
3.P3690 【模板】Link Cut Tree (动态树)
4.P4332 [SHOI2014]三叉神经树

被神仙叫做模板题。每棵平衡树在其中维护最深不是2的以及最深不是1的点。然

后乱搞就行。

(2)维护图连通性:

1.P2387 [NOI2014]魔法森林

排个序,维护一波。

2.P2542 [AHOI2005]航线规划

维护双连通,倒叙做

3.P4234 最小差值生成树

这里的话需要先新建节点,表示两点之间的边权。维护链的最小值,删掉就行。

4.P4172 [WC2006]水管局长

不知道为什么别人一个个跑得飞快。这道题,也就是维护一个最大边,形成一个

圈就删去即可。

(3)维护子树信息:

1.P4219 [BJOI2014]大融合

注意虚子树修改在\(link\)和\(access\)中要进行。

2.P3703 [SDOI2017]树点涂色

在浑浊的\(LCT\)中,这简直就是一股清流。

线段树\(dfs\)序来维护一棵子树的颜色总和。

每次将根到某个点的链全部染成同一种颜色就是一次\(access\)操作。于是乎

\(access\)每断一次边下面的原来链的子树答案加1,新加入的链的子树答案全部减

1

5.树链剖分

这是一个收集篇,收集树剖好题。

1.P4211 [LNOI2014]LCA

建个下标为标号的主席树的dfs序(维护区间差分个数)

6.扫描线

1.P1972 [SDOI2009]HH的项链

感受一下

2.P4113 [HEOI2012]采花

感受一下

3.P1856 [USACO5.5]矩形周长Picture

luogu无矩形面积并,不过这个也差不多。

跑两边扫描线,每次加差值就行。

4.P1502 窗口的星星

原文地址:https://www.cnblogs.com/powerYao/p/11445293.html

时间: 2024-11-01 21:47:39

数据结构(下)的相关文章

大数据技术之_16_Scala学习_08_数据结构(下)-集合操作+模式匹配

第十一章 数据结构(下)-集合操作11.1 集合元素的映射-map11.1.1 map 映射函数的操作11.1.2 高阶函数基本使用案例1+案例211.1.3 使用 map 映射函数来解决11.1.4 模拟实现 map 映射函数的机制11.1.5 课堂练习11.2 集合元素的扁平-flatMap11.3 集合元素的过滤-filter11.4 集合元素的化简-reduce11.5 集合元素的折叠-fold11.6 集合元素的扫描-scan11.7 集合的综合应用案例11.8 集合的合并-zip11

Redis学习——数据结构下

4.集合(集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素.) 1.命令 .集合内操作 1.添加元素 sadd key element [element ...]返回结果为添加成功的元素个数. 2.删除元素 srem key element [element ...]返回结果为成功删除元素个数. 3.计算元素个数 scard key (scard的时间复杂度为O(1),它不会遍历集合所有元素,而是直

Scala函数式编程(四)函数式的数据结构 下

前情提要 Scala函数式编程指南(一) 函数式思想介绍 scala函数式编程(二) scala基础语法介绍 Scala函数式编程(三) scala集合和函数 Scala函数式编程(四)函数式的数据结构 上 1.List代码解析 今天介绍的内容,主要是对上一篇介绍的scala函数式数据结构补充,主要讲代码.可以先看看上一节,主要讲的是函数式的list,Scala函数式编程(四)函数式的数据结构 上.这些代码我都放在我的公众号里面,包括函数式的List以及一个函数式的二叉搜索树,关注公众号:哈尔的

11. Scala数据结构(下)-集合操作

11.1 集合元素的映射-map映射操作 11.1.1 看一个实际需求 要求:请将List(3,5,8)中所有的元素都*2,将其结果放到一个新的集合中返回,即返回一个新的List(6,10,16),请编写程序实现 11.1.2 map映射操作    11.1.3 使用传统方法 -案例演示 object boke_demo01 { def main(args: Array[String]): Unit = { /* 请将List(3,5,8) 中的所有元素都 * 2 , 将其结果放到一个新的集合中

C#中使用Redis不同数据结构的内存占有量的疑问和对比测试

最近在大量使用Redis来进行数据统计前的清洗和整理,每天的数据量超5千万+,在开发过程中,数据量小,着重注意业务规则的处理,在上线基本测试后发现了大量的问题,其中之一就是Redis存储数据过多,内存的使用量大大增加.进过简单分析,对存储非常频繁的实体类进行了改进,字段名字进行缩写处理,一下子就减少了很多内存使用量.在对Redis的研究过程中,发现了以下这篇文章:Redis上踩过的一些坑-美团 ,发现其中 有一节内容:“四.redis内存使用优化 ”,对Redis不同的存储结构的使用量进行了对比

数据结构和算法概览(一)

软考视频第一章讲的就是数据结构.这部分的内容在自考书中学习过,曾经也接触过,总之,就是有一种熟悉的感觉.猛然间的看上去好像有非常多的数据结构,可是当把它们梳理好总结好以后,你会发现数据结构是如此的整齐. 计算机在解决不论什么实际问题都离不开数据表示和处理,而数据表示和处理核心的问题之中的一个就是数据结构. 数据结构就是计算机在组织数据和存储数据的方式.数据结构是计算机底层的知识,足够引起我们的重视,所以我们首先要从这样一个定位去学习它. 第一章能够分成两块内容.一是数据结构(包含逻辑结构和存储结

数据结构-从宏观上理解数据结构

注:本博文是本人对数据结构的理解,很多地方理解可能并不恰当,还请读者辩证的来学习 从宏观上理解数据结构 很多时候我们一直在埋头苦干,却不知道为什么这样...... 工作一年之后,重新回想一下大学里学的数据结构,发现所剩的寥寥无几,当提起某一种数据结构脑海中大体也只剩下了简单的定义,如跳表,也只是模糊记得是在一个有序链表上添加额外的指针来加快搜索速度,其他的似乎什么都不记得了,记得当时在学习数据结构时对跳表的理解还是蛮深刻的,然而时间一长却忘掉了关于跳表的大部分内容.之所以忘得这么快,一方面是由于

用js来实现那些数据结构15(图01)

其实在上一篇介绍树结构的时候,已经有了一些算法的相关内容介入.而在图这种数据结构下,会有更多有关图的算法,比如广度优先搜索,深度优先搜索最短路径算法等等.这是我们要介绍的最后一个数据结构.同时也是本系列最为复杂的一个.那么我们先来简单介绍一下,什么是图? 一.图的概念 简单说,图就是网络结构的抽象模型,图是一组由边连接的节点(或顶点).任何二元关系都可以用图来表示.比如我们的地图,地铁线路图等.都是图的实际应用. 接着我们看看图的一些相关概念和术语. 一个图G = (V,E)由以下元素组成: V

10.12 信号集

我们需要使用一种数据类型来存储多个信号,这种类型称为信号集,我们将在函数sigprocmask等函数中使用这些数据结构(下一节中),用于告知内核不要允许集合中的信号出现,正如我们早些时候提到的,不同信号的数量可能会超过一个整形变量的Bit数量,所以通常来说,我们不能使用整形变量中的每一个Bit来存储每一个信号.POSIX.1定义了数据结构sigset_t用存储信号集,并且允许如下五个函数对其进行操作: #include<signal.h> int sigemptyset(sigset_t*se

10.11 信号集

我们需要使用一种数据类型来存储多个信号,这种类型称为信号集,我们将在函数sigprocmask等函数中使用这些数据结构(下一节中),用于告知内核不要允许集合中的信号出现,正如我们早些时候提到的,不同信号的数量可能会超过一个整形变量的Bit数量,所以通常来说,我们不能使用整形变量中的每一个Bit来存储每一个信号.POSIX.1定义了数据结构sigset_t用存储信号集,并且允许如下五个函数对其进行操作: #include <signal.h> int sigemptyset(sigset_t *