zoukankan      html  css  js  c++  java
  • 做点字符串题

    547E. Mike and Friends
    题意:
    给定(n)个字符串(s_1,cdots,s_n),定义(f(i,j))(s_i)(s_j)作为子串出现次数.
    给出(q)个询问((l,r,k)),求(displaystylesum_{i=l}^rf(i,k).)
    首先只需要求(f(i,k))关于(i)的前缀和进行作差.然后考虑对(i)按顺序加入贡献,每次对(k)进行询问.
    第一种做法是使用AC自动机,如果(s_k)(s_{i1}cdots s_{im})的后缀,那么在fail树上(s_{i1}cdots s_{im})对应节点是(s_j)对应节点的后代.
    因此需要使用DFS序进行单点增加(1)和子树和询问.
    第二种做法是使用后缀数组,如果(s_k)(s_{im}cdots s_{i|s_i|})的前缀,那么在height数组中两者排名对应位置间所有数都大于或等于(|s_k|).
    使用单调栈和二分可以求出每个(s_k)在后缀数组中与它LCP大于或等于(|s_k|)的范围,然后同样使用单点修改和区间求和统计答案.
    如果记(m=sum_{i=1}^n|s|),两种做法复杂度都是时间(O(m+qlog m)),空间(O(m+q)).

    204E. Little Elephant and Strings
    题意:
    给定(n)个字符串(s_1,cdots,s_n)和整数(k),对每个字符串求有多少个子串存在至少(k)个字符串包含这个子串.
    显然如果(s_i[l,r])是答案,那么([l,r])的所有子区间([x,y])也是答案.因此可以使用双指针.
    想要验证(s_i[l,r])是答案,可以通过使用height数组二分在后缀数组上找到对应的区间,转换为区间求颜色数问题.
    由于只需要验证颜色数是否至少为(k),可以再次使用双指针来队每个区间左端点求出颜色至少为(k)的右端点中的最小值.
    时间和空间复杂度都是(O(mlog m)).

  • 相关阅读:
    9.5---所有字符串的排列组合(CC150)
    9.4---集合子集(CC150)
    9.3---魔术索引(CC150)
    5.3(2)----机器人走方格2(CC150)
    9.2---机器人走方格(CC150)
    9.1---上楼梯(CC150)
    5.3---找最近的两个数(CC150)
    5.8---像素设定(CC150)
    7.4---加法替代运算(CC150)
    4.9---二叉树路径和(CC150)
  • 原文地址:https://www.cnblogs.com/Heltion/p/13955848.html
Copyright © 2011-2022 走看看