HDU 5769 Substring(后缀数组)
【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5769
【题目大意】
在一个串中求出包含字母的子串个数,
只要存在一个字符不相等的子串即可视为不同的子串。
【题解】
因为要求存在字符不相等因此我们可以利用后缀数组统计,
后缀数组的h数组可以记录前后两个后缀的最长公共前缀这样子相同的前缀就不会被多次计算,
保存每个位置之后出现的最近的要求的字母的位置,
从该后缀的包含该字母的位置往后且不在最长公共前缀的范围内的位置都可以作为子串的右端点,
统计左端点,计算符合条件的右端点的数量总和就是答案。
【代码】
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1000005;
int T,Cas=1,n,Rank[N],sa[N],h[N],tmp[N],cnt[N],nxt[N];
char c,s[N];
void suffixarray(int n,int m){
int i,j,k;n++;
for(i=0;i<2*n+5;i++)Rank[i]=sa[i]=h[i]=tmp[i]=0;
for(i=0;i<m;i++)cnt[i]=0;
for(i=0;i<n;i++)cnt[Rank[i]=s[i]]++;
for(i=1;i<m;i++)cnt[i]+=cnt[i-1];
for(i=0;i<n;i++)sa[--cnt[Rank[i]]]=i;
for(k=1;k<=n;k<<=1){
for(i=0;i<n;i++){
j=sa[i]-k;
if(j<0)j+=n;
tmp[cnt[Rank[j]]++]=j;
}sa[tmp[cnt[0]=0]]=j=0;
for(i=1;i<n;i++){
if(Rank[tmp[i]]!=Rank[tmp[i-1]]||Rank[tmp[i]+k]!=Rank[tmp[i-1]+k])cnt[++j]=i;
sa[tmp[i]]=j;
}memcpy(Rank,sa,n*sizeof(int));
memcpy(sa,tmp,n*sizeof(int));
if(j>=n-1)break;
}for(j=Rank[h[i=k=0]=0];i<n-1;i++,k++)
while(~k&&s[i]!=s[sa[j-1]+k])h[j]=k--,j=Rank[sa[j]+1];
}
int main(){
scanf("%d",&T);
while(T--){
scanf(" %s",s); c=s[0];
scanf(" %s",s); n=strlen(s);
suffixarray(n,256);
int pre=-1;
for(int i=n-1;i>=0;i--){
if(s[i]==c)pre=i;
nxt[i]=pre;
}long long ans=0;
if(nxt[sa[1]]!=-1)ans=n-nxt[sa[1]];
for(int i=2;i<=n;i++){
int t=nxt[sa[i]];
if(t==-1)continue;
t=max(t,sa[i]+h[i]);
ans=ans+n-t;
}printf("Case #%d: %lld\n",Cas++,ans);
}return 0;
}
HDU 5769 Substring(后缀数组)的更多相关文章
- hdu 5769 Substring 后缀数组 + KMP
http://acm.hdu.edu.cn/showproblem.php?pid=5769 题意:在S串中找出X串出现的不同子串的数目? 其中1 <= |S| < $10^5$ 官方题解 ...
- HDU 5769 Substring 后缀数组
Substring Problem Description ?? is practicing his program skill, and now he is given a string, he h ...
- HDU 5679 Substring 后缀数组判重
题意:求母串中有多少不同的包含x字符的子串 分析:(首先奉上FZU官方题解) 上面那个题就是SPOJ694 ,其实这两个题一样,原理每次从小到大扫后缀sa数组,加上新的当前后缀的若干前缀,再减去重复的 ...
- hdu 1403 Longest Common Substring 后缀数组 模板题
题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- hdu_1403_Longest Common Substring(后缀数组的应用)
题目链接:hdu_1403_Longest Common Substring 题意: 给你两个字符串,然你找最长的公共子串 题解: 后缀数组的经典应用,要找两个字符串的公共子串,那么就相当于找两个串的 ...
- HDU 6194【后缀数组】
题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=6194] 题意: 给你一个长度不大于1e5的字符串,然后然你判断其子串严格出现k次的子串个数. 题解: ...
- POJ3693 Maximum repetition substring 后缀数组
POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...
- 2016多校联合训练4 F - Substring 后缀数组
Description ?? is practicing his program skill, and now he is given a string, he has to calculate th ...
随机推荐
- Linux学习之tail命令
tail 命令从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不但刷新, ...
- codeforces 10 D. LCIS LCIS O(n^2)算法
题目链接 给出两个序列, 求出他们的最长公共上升子序列. 两层循环, 内层循环j, 外层i. 如果a[i] == b[j], 那么dp[j] = max(dp[j], dp[best]+1), bes ...
- c语言 选择排序
选择排序 // int array[] = {3, 2, 6, 9, 8, 5, 7, 1, 4}; // int count = sizeof(array) / sizeof(array ...
- (译) 《Javascript 24条最佳实践》
(摘录) <Javascript 24条最佳实践> 自己一直偏向于实用主义,不是学院派,不是学究派,只讲究把东西能够很好的做出来,但经过一段时间的开发工作当自己总结出来一些东西时,觉得挺有 ...
- java实现发送短信
本程序是通过使用中国网建提供的SMS短信平台实现的(该平台目前为注册用户提供5条免费短信,3条免费彩信,这足够用于我们测试用了.在使用前需要注册,注册地址为http://sms.webchinese. ...
- [C#]Stream.Write Extension Method
在处理Stream型态时常会使用到Stream.Write这个方法,每次都会有种疑问就是,大多数的处理都是要将Buffer整个写入,為何偏偏每次都要将索引带0,长度带為Buffer的大小呢?另外在处理 ...
- 解决Robotium测试用例crash问题
今天遇到一个棘手的问题 用robotium框架真机测试客户端时 跑到一半会crash 搜了一堆资料终于解决了 我的程序引起crash主要原因有两个: 1.用Robotium测试框架跑多个用例(写在同一 ...
- git操作标签
操作标签 如果标签打错了,也可以删除: $ git tag -d v0.1 Deleted tag 'v0.1' (was e078af9) 因为创建的标签都只存储在本地,不会自动推送到远程.所以,打 ...
- date tod = boost::gregorian::day_clock::local_day(); //当前日期
boost 时间和日期 - 苦逼码农 - 博客频道 - CSDN.NET date tod = boost::gregorian::day_clock::local_day(); //当前日期
- 【转】Loss Function View
感谢原文作者!原文地址:http://eletva.com/tower/?p=186 一.Loss Function 什么是Loss Function?wiki上有一句解释我觉得很到位,引用一下:Th ...