UVALive 6869 Repeated Substrings
Repeated Substrings
Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu
Description
String analysis often arises in applications from biology and chemistry, such as the study of DNA and protein molecules. One interesting problem is to find how many substrings are repeated (at least twice) in a long string. In this problem, you will write a program to find the total number of repeated substrings in a string of at most 100 000 alphabetic characters. Any unique substring that occurs more than once is counted. As an example, if the string is “aabaab”, there are 5 repeated substrings: “a”, “aa”, “aab”, “ab”, “b”. If the string is “aaaaa”, the repeated substrings are “a”, “aa”, “aaa”, “aaaa”. Note that repeated occurrences of a substring may overlap (e.g. “aaaa” in the second case).
Input
The input consists of at most 10 cases. The first line contains a positive integer, specifying the number of
cases to follow. Each of the following line contains a nonempty string of up to 100 000 alphabetic characters.
Output
For each line of input, output one line containing the number of unique substrings that are repeated. You
may assume that the correct answer fits in a signed 32-bit integer.
Sample Input
3
aabaab
aaaaa
AaAaA
Sample Output
5
4
5
HINT
Source
解题:后缀数组lcp的应用,如果lcp[i] > lcp[i-1]那么累加lcp[i] - lcp[i-1]
#include <bits/stdc++.h>
using namespace std;
const int maxn = ;
int rk[maxn],wb[maxn],wv[maxn],wd[maxn],lcp[maxn];
bool cmp(int *r,int i,int j,int k) {
return r[i] == r[j] && r[i+k] == r[j+k];
}
void da(int *r,int *sa,int n,int m) {
int i,k,p,*x = rk,*y = wb;
for(i = ; i < m; ++i) wd[i] = ;
for(i = ; i < n; ++i) wd[x[i] = r[i]]++;
for(i = ; i < m; ++i) wd[i] += wd[i-];
for(i = n-; i >= ; --i) sa[--wd[x[i]]] = i; for(p = k = ; p < n; k <<= ,m = p) {
for(p = ,i = n-k; i < n; ++i) y[p++] = i;
for(i = ; i < n; ++i) if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = ; i < n; ++i) wv[i] = x[y[i]]; for(i = ; i < m; ++i) wd[i] = ;
for(i = ; i < n; ++i) wd[wv[i]]++;
for(i = ; i < m; ++i) wd[i] += wd[i-];
for(i = n-; i >= ; --i) sa[--wd[wv[i]]] = y[i]; swap(x,y);
x[sa[]] = ;
for(p = i = ; i < n; ++i)
x[sa[i]] = cmp(y,sa[i-],sa[i],k)?p-:p++;
}
}
void calcp(int *r,int *sa,int n) {
for(int i = ; i <= n; ++i) rk[sa[i]] = i;
int h = ;
for(int i = ; i < n; ++i) {
if(h > ) h--;
for(int j = sa[rk[i]-]; i+h < n && j+h < n; h++)
if(r[i+h] != r[j+h]) break;
lcp[rk[i]] = h;
}
}
int r[maxn],sa[maxn];
char str[maxn];
int main() {
int hn,x,y,cs,ret;
scanf("%d",&cs);
while(cs--) {
scanf("%s",str);
int len = strlen(str);
for(int i = ; str[i]; ++i)
r[i] = str[i];
ret = r[len] = ;
da(r,sa,len+,);
calcp(r,sa,len);
for(int i = ; i <= len; ++i)
if(lcp[i] > lcp[i-]) ret += lcp[i] - lcp[i-];
printf("%d\n",ret);
}
return ;
}
后缀自动机
#include <bits/stdc++.h>
using namespace std;
const int maxn = ;
int cnt[maxn],c[maxn],sa[maxn];
struct node{
int son[],f,len;
void init(){
memset(son,-,sizeof son);
f = -;
len = ;
}
};
struct SAM{
node e[maxn];
int tot,last;
int newnode(int len = ){
e[tot].init();
e[tot].len = len;
return tot++;
}
void init(){
tot = last = ;
newnode();
}
void add(int c){
int p = last,np = newnode(e[p].len + );
while(p != - && e[p].son[c] == -){
e[p].son[c] = np;
p = e[p].f;
}
if(p == -) e[np].f = ;
else{
int q = e[p].son[c];
if(e[p].len + == e[q].len) e[np].f = q;
else{
int nq = newnode();
e[nq] = e[q];
e[nq].len = e[p].len + ;
e[q].f = e[np].f = nq;
while(p != - && e[p].son[c] == q){
e[p].son[c] = nq;
p = e[p].f;
}
}
}
last = np;
cnt[np] = ;
}
}sam;
char str[maxn];
int main(){
int kase;
scanf("%d",&kase);
while(kase--){
scanf("%s",str);
sam.init();
memset(cnt,,sizeof cnt);
int len = strlen(str);
for(int i = ; str[i]; ++i)
sam.add(str[i]);
node *e = sam.e;
memset(c,,sizeof c);
for(int i = ; i < sam.tot; ++i) c[e[i].len]++;
for(int i = ; i <= len; ++i) c[i] += c[i-];
for(int i = sam.tot-; i >= ; --i) sa[--c[e[i].len]] = i;
for(int i = sam.tot-; i > ; --i){
int v = sa[i];
cnt[e[v].f] += cnt[v];
}
int ret = ;
for(int i = ; i < sam.tot; ++i){
if(cnt[i] <= ) continue;
ret += e[i].len - e[e[i].f].len;
}
printf("%d\n",ret);
}
return ;
}
UVALive 6869 Repeated Substrings的更多相关文章
- UVALive - 6869 Repeated Substrings 后缀数组
题目链接: http://acm.hust.edu.cn/vjudge/problem/113725 Repeated Substrings Time Limit: 3000MS 样例 sample ...
- CSU-1632 Repeated Substrings (后缀数组)
Description String analysis often arises in applications from biology and chemistry, such as the stu ...
- UVALive 6869(后缀数组)
传送门:Repeated Substrings 题意:给定一个字符串,求至少重复一次的不同子串个数. 分析:模拟写出子符串后缀并排好序可以发现,每次出现新的重复子串个数都是由现在的height值减去前 ...
- Repeated Substrings(UVAlive 6869)
题意:求出现过两次以上的不同子串有多少种. /* 用后缀数组求出height[]数组,然后扫一遍, 发现height[i]-height[i-1]>=0,就ans+=height[i]-heig ...
- UVALive 4671 K-neighbor substrings 巧用FFT
UVALive4671 K-neighbor substrings 给定一个两个字符串A和B B为模式串.问A中有多少不同子串与B的距离小于k 所谓距离就是不同位的个数. 由于字符串只包含a和 ...
- UVALive - 4671 K-neighbor substrings (FFT+哈希)
题意:海明距离的定义:两个相同长度的字符串中不同的字符数.现给出母串A和模式串B,求A中有多少与B海明距离<=k的不同子串 分析:将字符a视作1,b视作0.则A与B中都是a的位置乘积是1.现将B ...
- CSU-1632 Repeated Substrings[后缀数组求重复出现的子串数目]
评测地址:https://cn.vjudge.net/problem/CSU-1632 Description 求字符串中所有出现至少2次的子串个数 Input 第一行为一整数T(T<=10)表 ...
- LeetCode 1100. Find K-Length Substrings With No Repeated Characters
原题链接在这里:https://leetcode.com/problems/find-k-length-substrings-with-no-repeated-characters/ 题目: Give ...
- [LeetCode] Repeated DNA Sequences 求重复的DNA序列
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...
随机推荐
- Cocos2dx 小技巧(十五)话说ScrollView的delegate实现过程
附:本文參加了CSDN博客大赛.亲假设认为这篇文章不错,就大胆的来投上一票吧! !!http://vote.blog.csdn.net/Article/Details? articleid=34140 ...
- SVN版本号管理工具使用中常见的代码提交冲突问题的解决方法
相信刚開始学习使用SVN的小伙伴在项目合作开发的过程中一定常常遇到一些影响到自己编写的代码的苦恼.我这里列举了几种常见的问题以及问题的解决方法: 1.误删除和误操作的问题 问题1:有A和B两个人一块合 ...
- java中多线程知识
参考:http://www.cnblogs.com/wxd0108/p/5479442. 引 如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只 ...
- rest_framework-认证-总结完结篇
执行过程 APIView() Ruquest() Authentication() OrderView()APIView() def duspatch: self.initial(request) d ...
- AngularJs轻松入门(三)MVC架构
MVC应用程序架构最早于1970年起源于Smalltalk语言,后来在桌面应用程序开发中使用较为广泛,如今在WEB开发中也非常流行.MVC的核心思想是將数据的管理(Model).业务逻辑控制(Cont ...
- PostgreSQL Replication之第四章 设置异步复制(2)
4.2 配置级联复制 正如您在本章已经看到的,设置流复制真的很容易.只需要设置几个参数,做一个基础备份,并享受您的复制设置. 在许多情况下,这种情况更有一点点微妙.在这个例子中我们假设:我们要使用一个 ...
- Xrdp - 通过Windows的RDP连接Linux远程桌面(Ubuntu/CentOS/Redhat 7)(转载)
您多久访问一次Linux桌面? 您使用什么工具来访问远程桌面? Xrdp是一个开源工具,允许用户通过Windows RDP访问Linux远程桌面. 除了Windows RDP之外,xr ...
- TP5 belongsTo 和 hasOne的区别
hasOne和belongsTo这两种方法都可以应用在一对一关联上,但是他们也是有区别的: belongsTo: 从属关系:就是谁为主的问题 A:{id,name,sex} B:{id,name.A_ ...
- CF GYM 100781A(菊花图+直径)
题目大意 给出若干颗树用最少的边把它们连成一个无向连通图,同时使图的直径最小.输出最小直径. 题解 我们定义树的半径为(树的直径+1)/2.符合题意的连接方式为.所有树的“中点”连在直径最长的树的中点 ...
- django-debug-toolbar 使用
https://pypi.org/project/django-debug-toolbar/ https://django-debug-toolbar.readthedocs.io/en/latest ...