HDU5769 Substring(后缀数组)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5769

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
const int MAXN = 1e5+;
int t1[MAXN],t2[MAXN],c[MAXN];
bool cmp(int *r,int a,int b,int l)
{
return r[a] == r[b] && r[a+l] == r[b+l];
}
void da(int str[],int sa[],int rankk[],int height[],int n,int m)
{
n++;
int i, j, p, *x = t1, *y = t2;
//第一轮基数排序,如果s的最大值很大,可改为快速排序
for(i = ; i < m; i++)
c[i] = ;
for(i = ; i < n; i++)
c[x[i] = str[i]]++;
for(i = ; i < m; i++)
c[i] += c[i-];
for(i = n-; i >= ; i--)
sa[--c[x[i]]] = i;
for(j = ; j <= n; j <<= )
{
p = ;
//直接利用sa数组排序第二关键字
for(i = n-j; i < n; i++)
y[p++] = i;//后面的j个数第二关键字为空的最小
for(i = ; i < n; i++)
if(sa[i] >= j)
y[p++] = sa[i] - j;
//这样数组y保存的就是按照第二关键字排序的结果
//基数排序第一关键字
for(i = ; i < m; i++)c[i] = ;
for(i = ; i < n; i++)
c[x[y[i]]]++;
for(i = ; i < m; i++)
c[i] += c[i-];
for(i = n-; i >= ; i--)
sa[--c[x[y[i]]]] = y[i];
//根据sa和x数组计算新的x数组
swap(x,y);
p = ;
x[sa[]] = ;
for(i = ; i < n; i++)
x[sa[i]] = cmp(y,sa[i-],sa[i],j)?p-:p++;
if(p >= n)break;
m = p;//下次基数排序的最大值
}
int k = ;
n--;
for(i = ; i <= n; i++)rankk[sa[i]] = i;
for(i = ; i < n; i++)
{
if(k)k--;
j = sa[rankk[i]-];
while(str[i+k] == str[j+k])k++;
height[rankk[i]] = k;
}
}
int rankk[MAXN],height[MAXN];
int RMQ[MAXN];
int mm[MAXN];
int best[][MAXN];
char str[MAXN];
int r[MAXN];
int sa[MAXN];
int len;
int hxpos[MAXN];
int xpos[MAXN];
int main()
{
int t,cas;
__int64 sum;
char x[];
int i,n,cnt;
scanf("%d",&t);
for(cas=; cas<=t; cas++)
{
sum=;
scanf("%s",x);
scanf("%s",str);
len=strlen(str);
memset(xpos,-,sizeof(xpos));
cnt=;
for(i=; i<len; i++)
{
if(str[i]==x[])
xpos[cnt++]=i;
}
for( i = ; i < len; i++)r[i] = str[i]-'a'+;
r[len] = ;
da(r,sa,rankk,height,len,);
cnt=;
for(i=; i<len; i++)
{
while(xpos[cnt]<i&&xpos[cnt]!=-)
cnt++;
if(xpos[cnt]==-)
hxpos[rankk[i]]=len-i+;
else
hxpos[rankk[i]]=xpos[cnt]-i+;
}
for(i=; i<len; i++)
{
sum+=(__int64)(len-sa[i+]-max(height[i+],hxpos[i+]-));
}
printf("Case #%d: %I64d\n",cas,sum);
}
return ;
}
HDU5769 Substring(后缀数组)的更多相关文章
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- HDU 5769 Substring 后缀数组
Substring Problem Description ?? is practicing his program skill, and now he is given a string, he h ...
- hdu_1403_Longest Common Substring(后缀数组的应用)
题目链接:hdu_1403_Longest Common Substring 题意: 给你两个字符串,然你找最长的公共子串 题解: 后缀数组的经典应用,要找两个字符串的公共子串,那么就相当于找两个串的 ...
- 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 ...
- hdu 5769 Substring 后缀数组 + KMP
http://acm.hdu.edu.cn/showproblem.php?pid=5769 题意:在S串中找出X串出现的不同子串的数目? 其中1 <= |S| < $10^5$ 官方题解 ...
- HDU 5679 Substring 后缀数组判重
题意:求母串中有多少不同的包含x字符的子串 分析:(首先奉上FZU官方题解) 上面那个题就是SPOJ694 ,其实这两个题一样,原理每次从小到大扫后缀sa数组,加上新的当前后缀的若干前缀,再减去重复的 ...
- Substring (后缀数组 + 计数)
题意:求出字符串中包含了某个字符的字符序列不一样的数量. 思路:其实主要的是找出每个被包含字符的数量,假设除了目标字符之外的所有字符都不一样,那么应该就很好求了,但是显然不可能,所以我们可以枚举每一个 ...
- hdu 1403 Longest Common Substring 后缀数组 模板题
题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...
- POJ 3693 Maximum repetition substring ——后缀数组
重复次数最多的字串,我们可以枚举循环节的长度. 然后正反两次LCP,然后发现如果长度%L有剩余的情况时,答案是在一个区间内的. 所以需要找到区间内最小的rk值. 两个后缀数组,四个ST表,$\Thet ...
随机推荐
- 腾讯WEB前端开发面试经历,一面二面HR面,面面不到!
[一面]~=110分钟 2014/09/24 11:20 星期三 进门静坐30分钟做题. 填空题+大题+问答题 >>填空题何时接触电脑 何时接触前端运算符 字符串处理 延 ...
- 手动封装js原生XMLHttprequest异步请求
Code Object.extend =function(targetObj,fnJson){ //扩展方法,类似于jQuery的$.extend,可以扩展类的方法,也可以合并对象 for(var f ...
- 《CMake实践》笔记三:构建静态库(.a) 与 动态库(.so) 及 如何使用外部共享库和头文件
<CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...
- CentOS6.3搭建Nginx代理访问MongoDB GridFS图片资源
PHP可以直接读取MongoDB GridFS中的图片并显示到页面中,但对PHP的压力就大了.偶然机会,了解到Nginx可以代理访问,实现过程如下: 1.工具准备 安装一些必要的编译工具及库,这里是直 ...
- maven项目打包成可执行的jar
编写功能类: package com.hpay.FileToZkUtil; import java.io.File; import java.io.FileInputStream; import ja ...
- Python函数讲解
Python函数
- socket的IO多路复用
IO 多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. Linux Linux中的 select,poll, ...
- Droidbox恶意软件动态分析环境搭建
@author : Dlive 0x01 DroidBox简介 DroidBox是一款,可以获得以下信息 1.APK包hash值 2.网络通信数据 3.文件读写操作 4.网络通信,文件读写,SMS中的 ...
- python之OS模块详解
python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...
- HTML5本地缓存数据
//HTML5本地缓存数据 function putObj(key, data) { if (!!window.localStorage) { var obj = { "key": ...