• 国庆七天乐——第七天


    20171007

    【字符串算法】

    1. 模式匹配----kmp

    定义:next[i+1]是最大的j+1使得p[0~j]是p[0~i]的后缀

    通过这个next数组来跳过某些冗余计算

                           

    作用:当模式串p的长度为j的前缀是长度为i前缀的后缀时,若文本串在i+1的位置失配,则指针可跳到j继续尝试与j+1位置匹配

    如何求next指针

    假设已求得前i个next,要求next[i+1]

    设next[i]=j

    若p[j]!=p[i]则使j=next[j]

    若p[i]==p[j](或j出界)则next[i+1]=j+1(或0)

    【复杂度】

    可以证明或者从代码中简单地看出,kmp算法复杂度是O(n+m)

    简单匹配当不match的时候要回溯

    Kmp算法只需要每次不匹配的时候跳一次next即可

    复杂度降到了线性。

    证明:

    KMP 算法的时间复杂度由预处理和匹配两部分组成

    外层的 i 循环和内层的 j 循环是完全独立的,时间复杂度可以单独计算

    i循环的时间复杂度明显是 O(N)

    j本身有加有减,但易知其下降的总次数不会超过增加的总次数( j 每次固定+1,但每次至少-1)

    j 每次增加都随i加1,故增加的总量为N,j下降的次数不会超过N

    故 j 循环的时间复杂度也是 O(N)

    总过程的时间复杂度为 O(N) 总时间复杂度是 O(N + M)

    *********************例题*****************************

    1.Poj2406

    题意:给一个字符串,问字符串中有多少个循环

    根据kmp中next数组的性质来求解

    Next数组性质: p[0~j]是p[0~i]的后缀,A=B

    显然x=z,y=w

    又因为y=z

    所以x=y=z=w

    ……

    由数学归纳法,得x为原串的最小循环节

    2.NOI2014

    题意:给定一个长为L的字符串(L<=100W),求一个num数组,num[i]表示长度为i的前缀中字符串S’的数量,其中S‘既是该前缀的前缀也是该前缀的后缀,且|S'|*2<=i

    Kmp变式

    定义由i=next[i]转移到-1的步数是dep[i]

    从i跳到j<=i/2的位置,num[i]=dep[j] 想想为什么?

    然后就两次kmp就好了

    【字符串哈希】

    字符串具有离散性强,长度大等特点,不易比较

    如果给每个字符串一个数值做标签,比较的时候直接比较这个标签就能确定字符串是否匹配。

    这个标签就是字符串HASH函数

    常用的HASH函数(BKDR HASH):

    也有其他花式HASH函数,在此不一一例举

    参考资料: http://blog.csdn.net/djinglan/article/details/8812934

    代码:

    常用的seed值: 31131131313131131313..  

    例如我们取x=131

    求串s=pekinguniversity hash[s]

    Hash[s]=p*131^15+e*131^14+…+y*131^0

     

    那么如果要在文本中找到串s,只用维护一个长度为16的子串的hash值并与hash(s)比较即可

    维护长度为l的子串的hash

    设已知hash[s[ i-l+1 ~ i ]]=h,要求h1=hash[s[ i-l ~ i+1 ]]

    h1=(h-s[i-l+1]*seed^(l-1))*seed+s[i+1]*seed^0               

    ******************例题*******************************

    1. 1.     口吃的外星人

    题意:有一个外星人说的话里包含很多重复的字符串,如ababa包含两个aba,给定这个外星人说的一句话,找出至少出现m词的最长字符串,字符串长度4e4

    解法:二分答案L,判断长度L的子串最多出现多少次

    维护长度L的子串hash,若某hash值出现m次则有解

    复杂度O(n log n)

    【回文串manacher】

    对称轴可能是字符串中的一个位置或者一个间隙

    避免重复操作?

    把间隙变成字符!

    aba —> #a#b#a#

    abba —> #a#b#b#a#

    Def: r[i]->以i为对称轴的最长匹配半径

    e.g.

          0 1 2 3 4 5 6

          # a # b # a #

    r:    0 1 0 3 0 1 0

    r恰好是最长回文串的长度

    (因为加了#的缘故,所以字符串长度变成了两倍,而r是枚举最长子串的半径,所以r最长就是回文子串最长)

    先定义两个指针

    Pos:一个回文串的对称轴

    Max_r:max(pos+r[pos])                                              

    情况1:i<max_r,取j为i关于pos的对称位置

    当r[j]+i>max_r时,i~max_r的一段必然可以匹配成回文串

    而max_r+1的位置开始需要逐位匹配

    Max_r=i+r[i],pos=I

    情况2:i<max_r,取j为i关于pos的对称位置

    r[j]+i<=max_r

    r[i]=r[j]

    情况3:i>=max_r

    从i开始往右逐位匹配,max_r=r[i]+i

    ***********************例题*************************

    题目大意:

    就是现在给出一个长度为 n 的字符串(1 <= n <= 10^6)和一个正整数K(1 <= K <= 10^12)

    对于给出的长度为n的字符串如果其回文串的数量比K少则输出-1, 否则输出所有回文串中长度为奇数的最长的前K个回文串的长度的乘积, 结果对于19930726取模输出

    解法:

    首先可以用manacher算法确定每个位置的回文半径, 由于这里只需要长度是奇数, 所以不需要再原来的字符串的相邻两个字符之间插入未出现的字符, 直接在首尾添加好不同字符之后盘一遍manacher算法, 对于位置i为中心的回文半径R[i], 用dp[i]来表示相邻长度的回文串的数量差分(其实就是一个常用的前缀和技巧, 因为这里每次更新[1, R[i]]这个区间 + 1, 而只在所有更新完毕之后才查询所以没有必要使用树状数组, 直接根据每次更新的时候dp[1]++, dp[R[i] + 1]--, 最后后dp[1~i]的和就是最终ans[i]的值, 即长度为2*i - 1的回文串的数量,然后用快速幂就可以了

    【考试2】

    T1字符串

    Manacher板子

    T2动态规划

    状态压缩dp,估计深搜广搜优化一下也能过

    F(I,j,p)表示第i时间段选择课程为j,此时combo为p的最大收获量

    Add是j状态i时刻能获得的收获

    当状态与选课吻合时

    F(I,j,p)=max{f(I-1,k,p-1)}+add (1<=p<=10)

    当选课与状态不吻合时

    f(I,j,0)=max{f(i-1,k,p)+p*(p-1)/2}+add (0<=p<=10)

    T3图论

    最小生成树加dfs加贪心

    因为边是以亿为单位的1e8数量级,而且不同边价格不同,所以n-1条边结果一定最优,所以买边和访问是分开的两个问题。

    先最小生成树建边,把花费*1e8加入答案。

    Dfs计算访问一颗子树的时间T[i]和每颗子树的费用和sum[i]

    贪心,策略类似于国王游戏

    由于限制访问次数,访问子树时必定先遍历完一颗子树再去访问另一颗

    那么当存在两颗子树时,设T0,sum0,T1,sum1

    若先访问0,则1的等待时间和等待花销已知,为t0*sum1

    同理若先访问1,则0的花销为t1*sum0

    当t0/sum0<t1/sum1时,先访问t0更优

    对每个点的子树的ti/sumi排序

    顺序访问子树,转化为子问题,此题得解。

  • 相关阅读:
    WPF 基础到企业应用系列1——开篇有益
    WPF 基础到企业应用系列2——WPF前世今生
    “云计算之旅”筹备完成,意见征询!
    31天重构学习笔记30. 尽快返回
    作为资深程序员,必定会掌握的十句谎话
    TaffyDB Writing queries
    TAFFY Working with data
    2012年全球最愚蠢的设计第一是微软,第二还是微软
    TaffyDB Introduction
    TaffyDB Beginner's Guide
  • 原文地址:https://www.cnblogs.com/ZDHYXZ/p/7635550.html
Copyright © 2020-2023  润新知