http://acm.hdu.edu.cn/showproblem.php?pid=6194

题意: 给一个字符串,和一个k,问你串中出现k次的子串有多少个。

哎,我这次要背大大的锅,从多校开始好多字符串SA的题都在wa,wa,wa,昨天沈阳网选的也是一直处于懵逼状态。还是做题不够多,做题时想的不够啊。 dalao们都说sam(后缀自动机)也可以过,我还是回去补补自动机吧,之后再补一篇博客。

思路:
构建后缀数组后,我们已经把所有后缀全部处理出来了,之后我们对于k>1的情况,我们知道height数组代表着2个排名i,i-1后缀的公共前缀也就是lcp,那么我们按照K长度的区间查找,我们每次查找区间最小值,这个值就是这段区间内可能的结果,之后我们要看一下这段区间i~i+k-1,左边的height以及右边的height的最大值,因为如果存在值那么就说明多加了一部分所以要剪掉,之后如果出现了负值,那么就是为0的情况,之后我们慢慢遍历一遍即可。
对于k=1的情况,我们需要对于字符串总长度len,len-sa[i]代表 sa[i]为排名为i的后缀的起始位置,那么这一段就是可能出现的次数,之后我们减去两边(左边,右边的最大值即可),之后还是与0比较。

    #include <bits/stdc++.h>#define maxs 2020202#define mme(i,j) memset(i,j,sizeof(i))#define ll long longusing namespace std;char s[maxs];int c[maxs],wa[maxs];int wb[maxs],sa[maxs],height[maxs],ranks[maxs];void Getsa(int m,int n){int *x=wa,*y=wb,p=0;for(int i=0; i<m; i++) c[i]=0;for(int i=0; i<n; i++) c[x[i]=s[i]]++;for(int i=1; i<m; i++) c[i]+=c[i-1];for(int i=n-1; i>=0; i--) sa[--c[x[i]]]=i;for(int k=1; p<n; k<<=1,m=p){p=0;for(int i=n-k; i<n; i++) y[p++]=i;for(int i=0; i<n; i++) if(sa[i]>=k) y[p++]=sa[i]-k;for(int i=0; i<m; i++) c[i]=0;for(int i=0; i<n; i++) c[x[y[i]]]++;for(int i=1; i<m; i++) c[i]+=c[i-1];for(int i=n-1; i>=0; i--) sa[--c[x[y[i]]]]=y[i];swap(x,y);x[sa[0]]=0,p=1;for(int i=1; i<n; i++)if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])x[sa[i]]=p-1;else x[sa[i]]=p++;}}void gethei(){int k=0,len=strlen(s);for(int i=1; i<=len; i++) ranks[sa[i]]=i;for(int i=0; i<len; i++){if(k) k--;int j=sa[ranks[i]-1];while(s[j+k]==s[i+k])k++;height[ranks[i]]=k;}}void text(int n){printf("This is SA\n");for(int i=0; i<n; i++)printf("SA[%d] is %d\n",i,sa[i]);printf("\nThis is Height\n");for(int i=0; i<=n; i++)printf("h[%d] is %d\n",i,height[i]);}int sum[maxs<<2];void build(int rt,int l,int r){if(l == r){sum[rt]=height[l];return;}int mid =(l+r)>>1;build(rt<<1|1,mid+1,r);build(rt<<1,l,mid);sum[rt]=min(sum[rt<<1],sum[rt<<1|1]);}int ask(int al,int ar,int l,int r,int rt){if(al<=l&&ar>=r) return sum[rt];int mid=(l+r)>>1;int ans=1e9;if(mid>=al) ans=ask(al,ar,l,mid,rt<<1);if(mid<ar) ans=min(ans,ask(al,ar,mid+1,r,rt<<1|1));return ans;}int main(){int t,k;scanf("%d",&t);while(t--){scanf("%d",&k);scanf("%s",s);int len=strlen(s);Getsa(200,len+1);gethei();build(1,1,len);height[len+1]=0;// text(len);if(k>len){puts("0");continue;}int ans=0;if(k==1){for(int i=1;i<=len-k+1;i++){ans+=max(len-sa[i]-max(height[i],height[i+k]),0);}printf("%d\n",ans);continue;}for(int i=1;i<=len-k+1;i++){ans+=max(ask(i+1,i+k-1,1,len,1)-max(height[i],height[i+k]),0);}printf("%d\n",ans);}return 0;}

HDU 6194 string string string相关推荐

  1. HDU 6194:string string string

    参考博客:HDU 6194 string string string (2017沈阳网赛-后缀数组) 下面题解来自该博客 题意: 告诉你一个字符串和k , 求这个字符串中有多少不同的子串恰好出现了k ...

  2. HDU 6194 string string string

    HDU 6194 输入一个字符串,求出现K次得子串个数 我的做法是求出大于等于K次的子串个数-大于等于K+1次的子串个数 #include <stdio.h> #include <s ...

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

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

  4. hdu 6086 Rikka with String(AC自动机+状压dp)

    题目链接:hdu 6086 Rikka with String 题意: 给你n个只含01的串,和一个长度L,现在让你构造出满足s[i]≠s[|s|−i+1] for all i∈[1,|s|] ,长度 ...

  5. static string java_java:String类、static关键字、Arrays类、 Math类

    public voidStrMethodTest(){/** public int length () :返回此字符串的长度. * public String concat (String str) ...

  6. 转换ArrayList String 到String []数组[重复]

    本文翻译自:Convert ArrayList to String[] array [duplicate] This question already has an answer here: 这个问题 ...

  7. C#中的String和string有什么区别?还有ref关键字怎么用?

    String 和 string 没有区别 string 是 String 的别名 ref 关键字一般只用于函数参数中,这个参数是 struct 类型,而不是 class 类型 因为 class 类型在 ...

  8. shell中$后加引号有什么用($string和$'string')

    bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 有些时候在某些服务管理脚本中看到$"$string& ...

  9. 【错误记录】Kotlin 编译报错 ( Type mismatch: inferred type is String? but String was expected )

    文章目录 一.报错信息 二.解决方案 一.报错信息 Google Play 上架要求 Android 的编译版本 和 目标版本都要高于 30 才可以上传 ; 将 Android 的编译版本 和 目标版 ...

  10. C#String与string大小写的区别

    1.string是c#中的类,String是.net Framework的类(在c# IDE中不会显示蓝色)   2.C# string映射为.net Framework的String   3.如果用 ...

最新文章

  1. 小冰和她的兄弟姐妹们组团出道:唱歌跳舞写文章样样都会,而且都开放版权...
  2. Windows下各个盘中的文件夹属性变为隐藏,怎么取消隐藏属性
  3. WPF编程,TextBlock中的文字修饰线(上划线,中划线,基线与下划线)的使用方法。...
  4. XML——XML概述
  5. over oracle 不足补零,oracle的rank,over partition涵数使用
  6. 深度解析两大应用内测分发工具Pre.im与TestFlight
  7. 免费素材下载:200个超棒的矢量图标下载
  8. CString int转换
  9. Sharepoint 浅谈 [转]
  10. 计算机硬件性能检测报告,性能测试实验报告.doc
  11. 数学建模——正态分布检验
  12. win10激活--以专业版(professional)为例
  13. ##24点游戏程序实现算法(文末源代码)
  14. opencv读取16位色深图片
  15. 用IDEA创建基于Spring Cloud的Feign的微服务:服务接口、服务提供者、服务使用者分离
  16. led灯选用什么品牌的比较好?2022最新led光源品牌排行榜
  17. ROS2网络课程资料分享2019.10.26
  18. 操作系统学习笔记1--ucos
  19. python计算长方体体积最简单代码_C语言编程简单的小程序,计算长方体体积!...
  20. LibZXing二维码工具

热门文章

  1. linux http status404,解决问题:HTTP Status 404(The requested resource is not avail
  2. 4毛发渲染及着色方法
  3. php 神经网络,神经网络算法基础入门
  4. 《iPad开发从入门到精通》——6.6节系统设置
  5. WPS文字表格外计算功能配合书签使用公式轻松实现
  6. JavaScript 学习笔记(八)前后端交互;Ajax进行前后端交互
  7. 最小费用最大流(详解+模板)
  8. 【Linux】syscall系统调用原理及实现
  9. ubuntu18.04安装roboware studio
  10. Roboware安装