给定一个字符x和一个字符串。要求输出包含此字符的所有不同字串。

后缀数组可以计算一个字符串的所有不同字串,理解了原理就能做这题了。

对于每一个后缀i,将产生len-sa[i]-hight[i]的前缀,累加起来就是所有不同字串。这里要求字串必须包含x

也就是对于每一个后缀i,要减去不含x的前缀。

保存每一个x的位置,用lower_bound查询在此后缀中的第一个x,然后之前的都不计算到贡献当中。

dc3敲起来太慢了

 #include <cstdio>
#include <algorithm>
#include <cstring>
#define LL long long
//using namespace std; const int maxn = 1e5+;
#define F(x) ((x)/3+((x)%3 == 1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
int wa[maxn*],wb[maxn*],wv[maxn*],wss[maxn*]; int c0(int *r,int a,int b)
{
return r[a] == r[b] && r[a+] == r[b+] && r[a+] == r[b+];
}
int c12(int k,int *r,int a,int b)
{
if(k == )
return r[a] < r[b] ||(r[a] == r[b] && c12(,r,a+,b+));
else
return r[a] < r[b] ||(r[a] == r[b] && wv[a+] < wv[b+]);
}
void sort(int *r,int *a,int *b,int n,int m)
{
int i;
for(i=;i<n;i++) wv[i] = r[a[i]];
for(i=;i<m;i++) wss[i] = ;
for(i=;i<n;i++) wss[wv[i]]++;
for(i=;i<m;i++) wss[i] += wss[i-];
for(i=n-;i>=;i--)b[--wss[wv[i]] ] = a[i];
}
void dc3(int *r,int *_sa,int n,int m)
{
int i,j,*rn = r+n;
int *san = _sa+n,ta = ,tb=(n+)/,tbc=,p;
r[n] = r[n+] = ;
for(i=;i<n;i++) if(i% != ) wa[tbc++] = i;
sort(r+,wa,wb,tbc,m);
sort(r+,wb,wa,tbc,m);
sort(r,wa,wb,tbc,m);
for(p=,rn[F(wb[])] = ,i=;i<tbc;i++)
rn[F(wb[i])] = c0(r,wb[i-],wb[i]) ? p-:p++;
if(p < tbc) dc3(rn,san,tbc,p);
else for(i=;i<tbc;i++) san[rn[i]] = i;
for(i=;i<tbc;i++) if(san[i]<tb) wb[ta++] = san[i]*;
if(n%==) wb[ta++] = n-;
sort(r,wb,wa,ta,m);
for(i=;i<tbc;i++) wv[wb[i]=G(san[i]) ] = i;
for(i=,j=,p=;i<ta&&j<tbc;p++)
_sa[p] = c12(wb[j]%,r,wa[i],wb[j]) ? wa[i++]:wb[j++];
for(;i<ta;p++) _sa[p] = wa[i++];
for(;j<tbc;p++) _sa[p] = wb[j++];
}
void da(int str[],int _sa[],int _rank[],int _height[],int n,int m)
{
for(int i=n;i<n*;i++) str[i] = ;
dc3(str,_sa,n+,m);
int i,j,k = ;
for(i=;i<=n;i++) _rank[_sa[i]] = i;
for(i=;i<n;i++)
{
if(k) k--;
j = _sa[_rank[i]- ];
while(str[i+k] == str[j+k]) k++;
_height[_rank[i]] = k;
}
} int T;
int sa[*maxn],hehe[*maxn],rank[maxn],height[maxn];
int x;
char line[*maxn]; void debug(int n)
{
for(int i=;i<=n;i++)
{
printf("sa:%d rank:%d height:%d\n",sa[i],rank[i],height[i]);
}
} int main()
{
//freopen("input.txt","r",stdin);
scanf("%d ",&T);
int cas = ;
while(T--)
{
scanf(" %c %s",&x,line);
int len = strlen(line);
for(int i=;i<len;i++) hehe[i] = line[i];
int ch[maxn],cnt = ;
for(int i=;i<len;i++)
{
if(line[i] == x) ch[cnt++] = i;
}
ch[cnt++] = len;
da(hehe,sa,rank,height,len,);
//debug(len);
LL ans = ;
for(int i=;i<=len;i++)
{
int pos = ch[std::lower_bound(ch,ch+cnt,sa[i]) - ch] - sa[i];
ans += len -sa[i] ;
ans -= std::max(pos,height[i]);
}
printf("Case #%d: %I64d\n",++cas,ans);
}
}

HDU5769-Substring-多校#4-1006-后缀数组的更多相关文章

  1. Lexicographical Substring Search SPOJ - SUBLEX (后缀数组)

    Lexicographical Substrings Search \[ Time Limit: 149 ms \quad Memory Limit: 1572864 kB \] 题意 给出一个字符串 ...

  2. HDU 4691 Front compression (2013多校9 1006题 后缀数组)

    Front compression Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Othe ...

  3. 2016暑假多校联合---Substring(后缀数组)

    2016暑假多校联合---Substring Problem Description ?? is practicing his program skill, and now he is given a ...

  4. 2016多校联合训练4 F - Substring 后缀数组

    Description ?? is practicing his program skill, and now he is given a string, he has to calculate th ...

  5. HDU 4691(多校第九场1006) 后缀数组

    ...还能多说什么. 眼角一滴翔滑过. 一直以为题意是当前串与所有之前输入的串的LCP...然后就T了一整场. 扫了一眼标程突然发现他只比较输入的串和上一个串? 我心中突然有千万匹草泥马踏过. 然后随 ...

  6. 牛客网多校训练第一场 I - Substring(后缀数组 + 重复处理)

    链接: https://www.nowcoder.com/acm/contest/139/I 题意: 给出一个n(1≤n≤5e4)个字符的字符串s(si ∈ {a,b,c}),求最多可以从n*(n+1 ...

  7. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  8. HDU 5769 Substring 后缀数组

    Substring Problem Description ?? is practicing his program skill, and now he is given a string, he h ...

  9. HDU 5679 Substring 后缀数组判重

    题意:求母串中有多少不同的包含x字符的子串 分析:(首先奉上FZU官方题解) 上面那个题就是SPOJ694 ,其实这两个题一样,原理每次从小到大扫后缀sa数组,加上新的当前后缀的若干前缀,再减去重复的 ...

  10. csu 1305 Substring (后缀数组)

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1305 1305: Substring Time Limit: 2 Sec  Memory Limi ...

随机推荐

  1. 图解Redis之数据结构篇——字典

    前言     字典在Redis中的应用非常广泛,数据库与哈希对象的底层实现就是字典. 系列文章 图解Redis之数据结构篇--简单动态字符串SDS 图解Redis之数据结构篇--链表 图解Redis之 ...

  2. poj3984 广度搜索BFS

      迷宫问题 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1 ...

  3. elasticsearch判断索引是否存在

    一.判断索引是否存在 指定索引名,判断指定的索引是否存在集群中 /** * 判断指定的索引名是否存在 * @param indexName 索引名 * @return 存在:true; 不存在:fal ...

  4. UITableView套UITableView数据刷新

    https://www.jianshu.com/p/ee4b2bd54d08 网上关于tableview嵌套tableview的文章很多,纵览很多后发现有两点没有满足需求 把两个tableview放在 ...

  5. [python]解决Windows下安装第三方插件报错:UnicodeDecodeError: 'ascii' codec can't decode byte 0xcb in position 0:

    系统:win7IDE:pycharm Python版本:2.7 安装第三方插件是报错:  报错原因与编码有关,pip把下载的临时文件存放在了用户临时文件中,这个目录一般是C:\Users\用户名\Ap ...

  6. 使用Random类生成指定范围的随机数

    目的:要生成在[min,max]之间的随机整数 public class RandomTest { public static void main(String[] args) { ; ; Rando ...

  7. 校园电商项目(1) 基于SSM

    第一步:搭好环境 我这里使用Eclipse做本次的项目,tomcat.maven啥的怎么弄就跳过了ヾ(o・ω・)ノ 第二步:创建工程 我们首先创建一个maven项目,选择最后一个,创建完之后发现报错, ...

  8. 转:win7下git凭据导致无法clone代码

    win7下存在一个凭据管理的情况,如果旧凭据没有删除,用新账户是无法clone代码的. https://blog.csdn.net/qq_34665539/article/details/804082 ...

  9. Flutter路由管理

    第一点:push使用 1.pushNamed——Navigator.of(context).pushNamed('routeName'); 此种方法只是简单的将我们需要进入的页面push到栈顶,以此来 ...

  10. 老男孩python学习自修第十二天【常用模块之生成随机数】

    常用函数 import random random.random() 生成0到1之间的小数 random.randint(begin, end) 生成[begin, end]之间的整数 random. ...