学习笔记

来源:互联网 发布:linux的隐藏文件 编辑:程序博客网 时间:2024/06/01 12:31
7.19
挑战 读完素数相关,收获线段上的点的数量 和 区间素数个数


7.23


挑战 读完尺取法 联系没做


7.26


挑战 读完开关问题


8.2 算法导论


对一个多项式的乘法来说 o(n*n)是其算法复杂度最朴素的一种算法 无非是累计其乘 将其次数相等的项积


累积起来 这种方法也叫系数表达求多项式乘积 但是通过点值表示法我们可以降其复杂度降到O(nlogn)


这种方法按我现在看到的应该是对其复数根进行相关操作。




点值表示法


所谓点值表示法 是指用对应次数的未知数和函数值对描述这个多项式.


例如一个多项式的次数界是 n 那么我就需要 { (x0,y0),(x1,y1),(x2,y2).....(xn-1,yn-1)}


但是如果我需要的是两个多项式乘积 在我已知这两个多项式系数的情况下 我仍然需要n个点吗... ...


那不是有点舍本求末 难道是需要一个高斯方程组来解




关于解方程


书上所说的范德蒙德矩阵 是通过矩阵乘法偶造出一个类似 n元一次的线性方程组来解方程 这样的复杂度是


O(n的立方) 这样能求出它的系数我认 但是 接下来的拉格朗日公式为什么能求出系数... ...而且其


复杂度还是 o(n'平方)


那么浅显易懂来说 这个多项式 求值和求其系数是一个逆运算的过程




我们常说的快速傅里叶变换简单来是说只是离散傅里叶变化的优化方式,而离散傅里叶转换只能说一种将多项式-系数表示转换为


多项式-点值表示的手段,这种手段经过优化后是O(n2)的,我们仍然不满足,所以开发出快速傅里叶变换将这种复杂度降到了O(nlogn)


从离散傅里叶变化来看,他有两种方式一种是初始的,复杂度为O(n的立方)的,基于n元一次方程组的范德蒙德矩阵解法,这种解法,


相对于第二种来说较为常规,仅仅是解一个方程组而已。而第二种拉格朗日解法,则是通过对其点值进行操作,这种我没看懂他是怎么在


O(n2)的复杂度里将... ...嗯,他可能并不需要算出系数,他就是用点值表示法来表示方程


快速傅里叶变换


快速傅里叶变换是将两个多项式的点值转换为复数根的形式,然后通过运用复数的性质对其分治求解


其工作原理主要分为三布


1.将两个多项式的点值转换为复数根的形式


2.用点值表示法累乘求值.(不过话又说了回来如果我用点值求法 C(x)=A(x)*b(x)那么根据插值定理我这个2*n-1的次数界C多项式


不是应该需要2*n-2个点值对才能表示吗... ... 对于这一点 书上仅仅给出“我们只需要补全A,B多项式的大于n次方的系数为0就可以了


嗯,很随意”)


3.得出点值表示法后 仅需要用FFT的逆运算求得C多项式的系数表示法即可


嗯嗯 看看书,再看看小姐姐的入门手册 就开始实践




8.14 后缀数组第三天 还是想她 hhhhh


算法第一步 了解各参数意义


第一部是类基数排序 将数字视作数位 先将所有数的数值记录下来


嗯嗯 它是根据所有数组出现的累计次数作为参照


8.14 后缀数组第六天 想她 想她 想她 hhhhhhhhhhhh
8.19 后缀数组第十一天 终于快学完了


8.29 Trie树与多插哈夫曼树有点相似
8.30 Trie树 关于串排序 复杂度为线性时间*26(常数) 输出也为线性时间*26(常数)
     若一个字符串创建出来 就不是 NULL
8.31 poj2778 给定一个长度为n的字符串 问不包含给定字符串的排列组合有几种
AC自动机是一个字符串多项匹配的算法 他只能算我的一个字符串里 给定的子字符串出现了几次


这道题看了kuangbin的结题报告 发现他用了神奇的矩阵构造
正常来说 我们构造的矩阵是


| A       I     |     |  An-1   |     |  An  |
|                     |  *  |         |  =  |      |
|       0       I     |     |  S0     |     |  S1  |


当时这样记录的是总A的信息的 叠加


而不是我第一排的信息的叠加 用这个 只用增加一维就可以了 就很简单


9.10 zoj 3228 kmp与ac自动机之分 在kmp中我们常用的手段是对于pattern串做一个next数组 然后 对这个next数组 在


主串上进行查找匹配 好像也没有什么 分别 都是对pattern串做一个操作再在主串上做操作


zoj 3228 多串分别 查找匹配次数 小小变换 加一个在每个节点处加一个 cnt 记录query时经过的次数


然而 不重叠??? 这是什么操作




hdu6198 青岛网络赛 这一道拉拉推给我的公式是根据斐波那契数列的项来实现的 因为他用到了累加 所以 我很自然而然地想到 


构造一个Sn项作为结果的记录 嗯 当时在做没人出的1001 就没去细想 后来看题解 他是直接将 我的Ans作为一个递推项来实现


我觉得这样不符合正常思维逻辑 但是因为这一项是由前一项累计组成 所以能想到也不出意外 不过我是在得知Ans只与前两项


有关的情况下 才能推出的公式




hdu4511 小明的女友 这道题粗看是是一道图论 问最短路是什么 只不过加了几条边不能走 但是仔细看看会发现他暗示了许多东西


1-> 2 -> 3 不能走 这是一条限制条件 但是呢 他说1->2可以走  那不是我可以走到底 再看看数据规模 50 100 5 很符合ac自动机


的数据规模 嗯 


这道题 怎么做呢 想想之前 我们做过什么 有不能走这条路可以走多少次 这个用矩阵快速幂做 有必须走这条路可以走多少次 这个也


用矩阵快速幂做


hdu 2546 典型01背包题 题目没读清楚


说一下解题思路


题目中给出的限制条件是卡中不足五块钱 则无法进行任何操作


如果我忽略这个限制条件就是一个很简单的01背包


那我们就应该对这个五块钱做出一个分析  五块钱一下无法作出任何操作 那么就相当于五块钱的时候只能做出一次


操作 那么我们贪心的想 我只要让这五块钱发挥最大用处 买一个最贵的东西就行了 因为我只有一次操作 买便宜的很明显不如


买贵的 对整体贡献大 那么剩余的money我们对他走一个01背包就行了 嗯 试试


9/29 hdu 1540 Tunnel Warfare  poj 3667  Hotel poj 2828 Buy Tickets线段树区间合并三联


在hdu1540中 是查询一个点它所能连接的区间范围 而 poj3667中 他查询的一个是是否有一个区间为空
poj2828中同样查询一个区间是否为空 不过但从题目难度来看 我觉得是 hdu1540 < poj2828 < poj 3667
在hdu1540中 我所维护的是三个值 该区域最左起向右连续区间 该区域最右向左连续区间 该区间最大连续区间
最大连续区间的是该节点(step)的左子树(lson)的最大连续区间或右子树(rson)最大连续区间或其左子树(lson)的右连续长度
加上其右子树(rson)的左连续长度 三项中最大的一项
而其左连续区间则是由 其左子树(lson)的左连续区间 如果他的左连续区间覆盖了他的所有区间(l->r)那么 还要加上当前结点
右子树(rson)的左连续区间 这一点很好想 如果我覆盖了 那么如果 我中间是连续的 那么就应该连上


当前结点右连续区间同理


那么我为什么可以由这三项决定呢 左右子树 最大区间覆盖肯定是要纳入考虑规则的 那么 和理由上面一样 如果我中间连续起来了
那么这一段起到的贡献肯能超过左右子树的最大区间覆盖


在query操作中 我查询是 某一个节点的序号
如果这个节点的覆盖达到了全覆盖或者没有任何覆盖那么很明显应该返回 他的区间覆盖值
重点操作是 查询的叠加 
在正常的查询中 如果我查询的区间是一个中间断开的查询区间 那么就应该update(l,mid,lson)+update(mid+1,r,rson)


虽然这里是单点查询 他的总体含义应该不变 如果我下次查询的信息节点 不足以支撑我总体的信息需求 或者说 我信息缺失了
那么我就应该做出以上操作 


那么如果说 我查询的一点不在下一节点的信息缺失范围 那么我就很简单 直接update一下去


那么 我信息缺失的范围在什么地方呢


想想我们线段树定义的涵义 该节点区间内 从左端点往右的最大连续 从右端点往左的最大连续 该区间最大连续
其实理由也与上面一样 如果说 我的节点在下一次查询的左子树(lson)右连续或右子树(rson)的左连续的范围
那么我们肯定要往右子树的左连续区间或者左子树的右连续区间继续追加查询了 


那么我就要问了 这么查询可以 那么为什么 我不考虑如果 我这个节点正好在我一个左子树的左连续区间内呢?
为什么我不要向左左子树(左隔壁的子树)查询呢(右子树的右连续区间一样)
其实 我们已经走了这一步了 如果他在我左子树的左连续区间内 那么也肯定在他父节点的右子树左连续区间内呀
那么我们不是已经走了在我右子树(rson)的左连续区间了吗


那么这道题 我就做完了 其实这道题只要掌握 到底 我区间之间的信息的继承就可以了呀


poj3667 hotel 


这道问我们的是在所有区间里 有没有一段连续的区间正好是空的 如果是空的就插入 然后还有一个操作 是把一段连续的区间清空


很明显的一个区间更新 在我看来 就是上面一道题的区间更新加强版(= V =) 然后我就开始想了 区间更新最重要的操作是什么 


是push_down() 那么 这里我该怎么写呢  就是很普通的一个区间更新 如果 我是清楚操作 就把这一段区间全部重置 就和build一样


如果 是插入 那么我就把它全置为0 很简单吧 但是我想了好久QAQ 其实我一直在纠结这个状态lazy的延续问题 


这一个query就用了我们上一题左右子树中间信息合并的方法。
如果说 我查询的是一个区间范围 这个区间范围 正好在我的左子树就满足了 那么我就顺着左子树找就可以了 
如果不行 我就先看看 我左右子树中间的那一段满不满足 如果ok 行那么直接返回就行了 
如果还是不行 那就肯定在右子树了 顺着右子树找就可以了


这道题倒是没有上面一道题脑洞这么大 神奇的想法一个一个出


poj2828 Buy Tickets
这道题其实是一个思维题 重要的是想到插入(update)的方式但我觉得也有点区间合并的意思 他也同样用了 该区间是否为空的标记