zoukankan      html  css  js  c++  java
  • 7.15

    数据结构

    堆:就是priority_queue

    讲完了  ------------------by dms

    树上倍增qwq

     作用:求最短路(在树上)

    A走到lCA+B走到LCA就是最短路

    lca求法:

    朴素:

    求出每个节点的深度

    step1:如果a的深度比b的深度小,就交换a,b(为了处理方便)

    step2:把a跳到b的深度(a不停的向上跳,当a,b处于同一深度的时候停止)

    step3:a,b一起向上跳,直到a=b为止

    复杂度:O(深度)

    我们发现这时如果树是个链的话就炸了

    我们想想怎么优化

    我们可以在向上跳的时候优化(也就是2,3步)

    我们设p[x][i]表示x的2i的祖先节点,so p[x][i]=p[p[x][i-1]][i-1]

    why?就像爷爷是爸爸的爸爸一样

    step2优化:a和b会有深度差delta,我们把delta转换为二进制,如果delta的第i位是1,则a就变成p[a][i](注意这里从高位到低位循环)

    step3优化:我们发现a,b到了lca之后,再往上跳就都一样了,我们很难确定lca,但是可以确定lca的儿子,即最浅的a≠b的位置。

    我们循环i从16(当然也可以是20神马的)到0,如果p[a][i]≠p[b][i],则让a=p[a][i],b=p[b][i],一直向上跳

    我们还可以用lca求树上任意两个点的路径

    我们求出根到a的路径+根到b的路径,再减去2*根到lca的路径

    其实差分问题都可以用lca来做辣(比如还有乘法什么的)

    用途:查询[l,r]的区间最大值,不支持修改

    mx[i][j]表示[i,i+2j-1]这个区间的最大值,可以预处理

    查询:求出区间长度l,那log2l就可以把整个区间分成两段(可能会有重叠,不过木有瓜系),设j=log2l,那查询的区间就是max(mx[i][j],mx[r-(1<<j)+1][j](这里i是左端点,r是右端点)

    预处理:st[i][j]=max(st[i][j-1],st[i+1<<(j-1)][j-1]

    神马是哈希?就是一个函数。平常说的哈希就是将一个字符串转成一个数。

    怎么整???

    我们先考虑一个字符串是几进制的数(是几进制看心情咯,不过建议取一个大于字符集大小的质数)

    然后暴力计算,如果字符串里面有数字肿么办?

    取ASCLL码值呗。然后我们发现转着转着就爆了,所以我们要取模。可以模大质数,也可以自然溢出(unsigned longlong)

    HASH有冲突怎么办?认命双重哈希,就是设计两个模数。如果还用冲突,那就3个

    我们现在能够求出一个整串的哈希,但是我们想要求子串,怎么办?

    我们可以求每个前缀的哈希值

    举个栗子:dingmingshuohaokeai

    d:d

    di:d2+i

    din:d3+i2+n

    ding:d4+i3+n2+g

    有什么用呢?

    假设我们要求ing的哈希,那f(ing)=f(ding)-f(d)*p3

    那化成一般的式子就是f(子串)=f(前缀)-f(不是子串的部分)*p子串长度

    即hash(i,j)=hash(j)-hash(i-1)*pj-i+1

    要求:快,准,尽可能避免冲突(只有神仙能做到qwq)

     

    上面是路径压缩qwq

    用fa[x]表示x的父亲.

    合并a,b:让a的祖宗认b的祖宗为爹。

    找x的祖宗:如果x的祖宗是自己,就返回x,否则返回fa[x],这里常用路径压缩进行优化,即返回时顺带把x的父亲,爷爷等等的fa都改成x的最高的祖宗

    树状数组

    我们接下来要种几棵线段树

    线段树是用来干什么的呢?当然是等它开花结果卖钱了(雾)

    线段树支持区间(单点)修改,区间(单点)查询

    我们种下线段树之后第一步是什么?给树浇水(雾)

    我们先来考虑又直接又暴力的单点修改

    就直接修改呗,都说了很暴力辣

    那区间查询呢?

    我们递归找答案。如果当前节点表示的区间被要求的区间完全覆盖,就不用往下再递归了,直接返回。否则看要求的区间与当前节点的哪个儿子有交集。哪个有交集就递归哪个。

    我们再来考虑区间修改。

    我们发现暴力区间修改的复杂度是O(nlogn)的,比不用线段树还慢qwq

    所以我们需要懒标记来加速

    这样就很像我们的区间查询了。也是递归在区间上打懒标记,递归的规则与区间查询一样。

    有了懒标记就要注意了,如果我们不是对节点代表的这整个区间进行操作,那就要标记下传(不管是查询还是修改)。

    代码

    qwqqwq

    n个节点,n-1条边,说明这个图是棵树

    对三个人两两求lca,会有以下三种情况(其中ABC分别代表那三个人)

    我们发现一定会有两组lca是重复的,那剩下那个不同的lca就是集合地点辣

     (打表找规律得,没有证明)

    qwqqwq 

    维护两个堆,一个大根堆,一个小根堆。一直往大根堆里面塞,保证大根堆里面的元素少于k/2+1个。如果出现元素个数≥k/2+1,就弹掉堆顶,把堆顶塞进小根堆。这样的大根堆堆顶就是答案。

    我们发现,越先被合并的那堆被算进答案的次数就越多,所以我们要合并尽可能小的两堆

    贪心完毕,没有代码

    据说这是哈夫曼树的模型

    太难了不会qwq

     这里可以由低海拔的点走到高海拔的点,其中T是输入给定的

    我们按照相邻两个格子的高度差建边。

    那这玩意不就是第T-1短的边权吗

    推导:由于T已知,而且n-1条边可以连通n个点,那么当连了T-1条边的时候,就能够到达T个点了。为了让D最小,所以我们先把所有的边按照边权(也就是高度差的绝对值)从小到大排序,然后一条一条的连边。这时D=第T-1短的边权

    (树状数组模型1)

    我们先想暴力怎么求逆序对数

    我们可以双重循环扫描比i大且在i前面出现的的所有j,然后加一加

    我们在暴力的基础上再进行一番优化

    我们发现,每次枚举i都暴扫一遍真的很浪费有木有,那怎么统计i与1~i-1到底构成了多少个逆序对呢?

    我们把ai的权值作为树状数组的下标,每出现一次权值为i的数,那就对树状数组进行一次操作(从c[i]开始),然后sum(a[i])就是比a[i]小的数出现的次数,那比a[i]大的数出现的次数就是i-sum(a[i])

    然后我们发现空间炸了,因为a[i]实在是太大了

    那我们可以离散化对吧

    然后就能A了

    在这里因为y是递增的,所以我们可以无视掉y的存在,然后只要求x<当前的x的所有星星就行了

    我们注意到m肥肠之小

    所以开m个树状数组进行操作

    每个树状数组的c[i]记录下标为i的序列中的数%m后是否等于当前这个树状数组的编号

    如果要改变,就直接改,如果要查询,就在第mod个树状数组里面查询,sum(r)-sum(l-1)就是答案

     一:平衡树(set,splay)因为保证有序,所以只需要比较前驱和后继哪个更靠近当前查询的数就好了

    二:线段树qwq

    以权值为下标,建立线段树

    维护区间最小值,区间最大值

    以当前查询的数为界,看左边区间的最小值,右边区间的最大值比较哪个更靠近当前查询的数

    线段树板子2qwq

    我们想到求斐波那契数列可以用矩阵乘法,对于ai+x,就相当于原来的数*矩阵的x次方

    式子如下:

    然后线段树维护矩阵加的和就好了

    qwq

    在昨天分块的时候说到longlong 以内的数最多被开6次根号,就会成熟。这个题也是利用这个性质。如果这个区间他没有成熟,就暴力开根,如果成熟了,就不要管他。求和就线段树求和。

    从5入手emm

    要关注小的数或者是取模数,这一般是入手点

    我们开一个s数组,s[i]记录mod 5=i的下标对应的数的和

    线段树的节点记录对应区间上的s数组

    序列:0 1 2 6 7 8 9 11

    合并:我们发现合并区间[1,2]的时候,只需要把10000向右转一位即可

    即看当前节点对于其父节点来说是左子树还是右子树,如果是右子树就转1位,左子树不转

    mex:当前区间内的没有出现过的最小的非负整数。                                                                                              这道题我们要离线做(在线做是真的不好做)                                       

    我们按照询问的l排序。接下来我们可以求出1~i的mex(也就是前缀)                                                                我们再考虑1~i的mex和2~i的mex有什么关系。如果a[1]要小于1~i的mex,那么2~i的mex就是a[1]                        推广到一般的r-l的mex与r-l+1的mex,就是让后面大于a[l]的mex变为a[l]就好了辣                                               

     len至少是3,那我们只要找到一个len等于3的等差序列,就有解了

    我们开一个bool数组p,p[当前出现过的数]=1

    不断枚举作为等差数列中间项的数,检查这个数两边的01是否对称,如果不对称,则证明没有出现的那个数在后面一定会出现(因为是1到N的排列),此时一定有解。如果一直对称,则无解

  • 相关阅读:
    [SAM4N学习笔记]UART的使用
    [SAN4N学习笔记]使用SysTick精准延时
    [SAM4N学习笔记]LED点灯程序
    [SAM4N学习笔记]SAM4N工程模板搭建
    C#用大石头Xcode做数据底层注意事项
    C#MVC中@HTML中的方法
    js比较时间大小(时间为以-分割的字符串时)
    C#后台Post提交XML 及接收该XML的方法
    jq对象和DOM对象的互换
    获取和设置HTML标签中的数据
  • 原文地址:https://www.cnblogs.com/lcez56jsy/p/11190917.html
Copyright © 2011-2022 走看看