题目链接:点击查看

题目大意:给出一个字符串 s 和一个字符 ch,问字符串 s 中有多少个本质不同的子串包含字符 ch

题目分析:其实就是求本质不同的子串加了一点条件,对于每个sa[ i ],其本质不同的子串的个数原本为 len - sa[ i ] - height[ i ],现在需要比较一下这个值与包含sa[ i ]在内,之后首次出现字符 ch 的距离所组成的后缀长度,具体实现看代码就好了,其实用后缀自动机也可以做,因为每次添加一个字符后,会产生 len[ i ] - len[ fa[ i ] ] 个本质不同的字符串,且都是连续的,可以二分找到最长含有字符 ch 的位置,其实本质上和后缀数组的做法一样,只不过时间复杂度可能会小一点

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e5+100;char str[N];int sa[N]; //SA数组,表示将S的n个后缀从小到大排序后把排好序的
//的后缀的开头位置顺次放入SA中
int t1[N],t2[N],c[N];int rk[N],height[N],len;int s[N];int nx[N];void build_sa(int s[],int n,int m)//n为添加0后的总长
{int i,j,p,*x=t1,*y=t2;for(i=0;i<m;i++) c[i]=0;for(i=0;i<n;i++) c[x[i]=s[i]]++;for(i=1;i<m;i++) c[i]+=c[i-1];for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;for(j=1;j<=n;j<<=1) {p=0;for(i=n-j;i<n;i++) y[p++]=i;for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;for(i=0;i<m;i++) c[i]=0;for(i=0;i<n;i++) c[x[y[i]]]++;for(i=1;i<m;i++) c[i]+=c[i-1];for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];swap(x,y);p=1,x[sa[0]]=0;for(i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;if(p>=n) break;m=p;}
}void get_height(int s[],int n)//n为添加0后的总长
{int i,j,k=0;for(i=0;i<=n;i++)rk[sa[i]]=i;for(i=0;i<n;i++) {if(k) k--;j=sa[rk[i]-1];while(s[i+k]==s[j+k]) k++;height[rk[i]]=k;}
}void solve(int base=128)
{build_sa(s,len+1,base);get_height(s,len);
}int main()
{
//#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
//#endif
//  ios::sync_with_stdio(false);int w;cin>>w;int kase=0;while(w--){char ch[5];scanf("%s%s",ch,str);len=strlen(str);for(int i=0;i<len;i++)s[i]=str[i]-'a'+1;s[len]=0;solve(30);//跑后缀数组 nx[len]=nx[len+1]=inf;for(int i=len-1;i>=0;i--)//nx[i]:第i位后首次出现ch字符的位置 {nx[i]=nx[i+1];if(str[i]==ch[0])nx[i]=i;}LL ans=0;for(int i=1;i<=len;i++){if(nx[sa[i]]==inf)//后面没有符合条件的字符串了 continue;ans+=min(len-sa[i]-height[i],len-nx[sa[i]]);}printf("Case #%d: %lld\n",++kase,ans);}return 0;
}

HDU - 5769 Substring(后缀数组)相关推荐

  1. HDU 5769 Substring(后缀数组)

    Substring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...

  2. 牛客-139 I. Substring(后缀数组 or 后缀自动机)

    牛客-139 I. Substring(后缀数组 or 后缀自动机) 题目链接 题意 一个由{a,b,c}\{a, b, c\}{a,b,c}组成的字符串SSS,求S子串的最大的集合,使得集合里的字符 ...

  3. Boring counting HDU - 3518 (后缀数组)

    Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...

  4. HDU 5769 Substring

    后缀数组. 然后按照排序完成之后的顺序,每个后缀统计贡献量. 统计第i个后缀的贡献的时候,如果这个后缀中没有X,贡献度为0. 有贡献的分3种情况考虑: 1.如果这个后缀height部分等于0(即与前一 ...

  5. POJ - 3693 Maximum repetition substring(后缀数组+RMQ)

    题目链接:点击查看 题目大意:给出一个字符串,求出字符串中 重复次数最多的连续重复子串 ,如果有多个答案,输出字典序最小的 题目分析:又是一个模板题,这里放一个大佬的博客,讲的很清楚: https:/ ...

  6. POJ-3693 Maximum repetition substring 后缀数组

    题目链接:http://poj.org/problem?id=3693 求字符串的重复次数最多的且字典序最小的字串. 很不错的题目.罗穗骞大牛论文的模板题,摘了Neo / Add ~0U>> ...

  7. hdu 5008 Boring String Problem(后缀数组+rmq)

    题目链接:hdu 5008 Boring String Problem 题意: 给你一个字符串,有q个询问,每次询问该字符串所有的子串中字典序第k小的是哪个串,输出位置,如果有多个位置,输出最靠左的那 ...

  8. 后缀数组 --- HDU 3518 Boring counting

    Boring counting Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3518 Mean: 给你一个字符串,求:至少出 ...

  9. HDU 6194 string string string :后缀数组+单调队列 | 后缀自动机

    题意:给出一个字符串,求出出现了恰好k次的子串的个数. 题解:恰好k次 = 至少k次 - 至少k+1次.答案转化为求至少出现k次的子串个数统计.构造好后缀数组以及很重要的Height数组之后.用一个k ...

最新文章

  1. [NC15034]德玛西亚万岁
  2. os.chdir用法
  3. python语言程序设计2019版第二章课后答案-《python语言程序设计》_第二章编程题...
  4. 061_html字符实体
  5. git pull代码出现refusing to merge unrelated histories错误
  6. css盒模型和元素绘制
  7. 如何判断自己的编程水平
  8. CSS Center(居中专题)
  9. 正态总体样本的分布定理
  10. Photoshop cc 2019 破解教程
  11. 小程序下找地点、查路线、搜地铁,用这3个插件就够了!
  12. 电动汽车结构原理基础知识
  13. Lwip之PPP、PPPoE实现(一)
  14. Django CSRF Bypass 漏洞分析(CVE-2016-7401)
  15. VUE 物理返回键的处理
  16. SAP中复制创建采购申请的过程
  17. Input框内容改变触发事件,实现表格动态模糊查询
  18. MATLAB如何保存高质量大图
  19. 短信平台验证码的特点
  20. nodejs:fs (内置模块)读取和写入文件

热门文章

  1. lisp语言画阿基米德线_孩子总说“我不会画”!那么孩子是否要先学画形象?...
  2. DOCKER OVERLAY2占用大量磁盘空间解决办法
  3. java 生成sql脚本_java导出insert语句并生成sql脚本
  4. MySQL高级in和not in
  5. 搜索引擎其实是一个读库
  6. Swagger2介绍
  7. InvalidClassException异常_原理和解决方案
  8. CSDN博主排名更新公告
  9. spring事务管理-演示事务的环境准备
  10. mongodb语法与spring实现