【UVA10829】 L-Gap Substrings (后缀数组)
Description
If a string is in the form UVU, where U is not empty, and V has exactly L characters, we say UVU
is an L-Gap string. For example, abcbabc is a 1-Gap string. xyxyxyxyxy is both a 2-Gap string
and also a 6-Gap string, but not a 10-Gap string (because U is non-empty).
Given a string s, and a positive integer g, you are to find the number of g-Gap substrings in s. s
contains lower-case letters only, and has at most 50,000 characters.Input
The first line contains a single integer t (1 ≤ t ≤ 10), the number of test cases. Each of the t followings
contains an integer g (1 ≤ g ≤ 10) followed by a string s.Output
For each test case, print the case number and the number of g-Gap substrings. Look at the output for
sample input for details.Sample Input
2
1 bbaabaaaaa
5 abxxxxxabSample Output
Case 1: 7
Case 2: 1
【题意】
UVU形式的串的个数,V的长度规定,U要一样,位置不一样即为不同字串
【分析】
表示做了poj3693还是不会做这题。
为什么会想到枚举L然后分块呢????
为什么呢????
这种方法于我而言还是有点难理解的啊。
主要是分块!!

任意一个满足条件的UVU,假设U的长度是len,那么左端的U必然包含按照len切分的T串的某个字串,及0,len,2len,3len...。(这点要仔细想清楚)
那么枚举每个端点i*len,然后利用RMQ求后缀i*len和后缀i*len+L+len的LCP,然后字符串T反向,再求一遍反向的LCP2。(其中LCP要小于等于len,否则会重复,仔细想清楚)
最后累加求和sum+=(LCP+LCP2-1)-len+1。(这点想清楚为什么是-len)
blog:http://blog.csdn.net/u011526463/article/details/14000693
还有,其实,貌似不用后缀数组直接两个while前后就可以了。时间貌似还是nlogn的。 【(2017-03-24 14:43:33)许多年后发现以前在搞笑。。
】
代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxl 100010 int l,len;
char s[Maxl];
int c[Maxl],cl; int mymin(int x,int y) {return x<y?x:y;} void init()
{
scanf("%d%s",&l,s);
len=strlen(s);
cl=;
for(int i=;i<len;i++) c[++cl]=s[i]-'a'+;
} int sa[Maxl],rk[Maxl],y[Maxl],wr[Maxl],Rs[Maxl];
void get_sa(int m)
{
memcpy(rk,c,sizeof(rk));
for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[rk[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[rk[i]]--]=i; int ln=,p=;
while(p<cl)
{
int k=;
for(int i=cl-ln+;i<=cl;i++) y[++k]=i;
for(int i=;i<=cl;i++) if(sa[i]>ln) y[++k]=sa[i]-ln;
for(int i=;i<=cl;i++) wr[i]=rk[y[i]]; for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[wr[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[wr[i]]--]=y[i]; for(int i=;i<=cl;i++) wr[i]=rk[i];
for(int i=cl+;i<=cl+ln;i++) wr[i]=;
p=,rk[sa[]]=;
for(int i=;i<=cl;i++)
{
if(wr[sa[i]]!=wr[sa[i-]]||wr[sa[i]+ln]!=wr[sa[i-]+ln]) p++;
rk[sa[i]]=p;
}
ln*=,m=p;
}
sa[]=rk[]=;
} int height[Maxl];
void get_he()
{
int k=;
for(int i=;i<=cl;i++) if(rk[i]!=)
{
int j=sa[rk[i]-];
if(k) k--;
while(c[i+k]==c[j+k]&&i+k<=cl&&j+k<=cl) k++;
height[rk[i]]=k;
}
} int d[Maxl][];
void rmq_init()
{
for(int i=;i<=cl;i++) d[i][]=height[i];
for(int j=;(<<j)<=cl;j++)
for(int i=;i+(<<j)-<=cl;i++)
d[i][j]=mymin(d[i][j-],d[i+(<<j-)][j-]);
} int rmq(int x,int y)
{
int t;x=rk[x];y=rk[y];
if(x>y) t=x,x=y,y=t;
x++;
int k=;
while((<<k+)<=y-x+) k++;
return mymin(d[x][k],d[y-(<<k)+][k]);
} void ffind()
{
int ans=;
for(int i=;i<=cl;i++)
{
for(int j=;j<=cl/i;j++)
{
int now=j*i+,x,y=;
if(c[now]!=c[now+l+i]||now+l+i>cl) continue;
x=mymin(i,rmq(now,now+l+i));//向后匹配
while(c[now-y-]==c[now+l+i-y-]&&y+<i) y++;//向前匹配
if(x+y-i+>) ans+=x+y-i+;
}
}
printf("%d\n",ans);
} int main()
{
int T,kase=;
scanf("%d",&T);
while(T--)
{
init();
get_sa();
get_he();
rmq_init();
printf("Case %d: ",++kase);
ffind();
}
return ;
}
[UVA10829]
2016-07-19 15:44:08
这道题我看了100遍!!
现在又明白了一点了ORZ。。。分块屌ORZ。。。

好吧,是按照u的长度分块!!
为什么呢,目的是:答案串的u至少包含一个分割点(上面的蓝色突起)
我们对于其包含的第一个分割点时计算他!!!(就是上面红色圈起的部分)
如果匹配长度越过第二个分割点,那么是会重复计算的,所以在这一题,向前匹配和向后匹配都可以直接while,越过分割点的时候就结束。
ORZ。。。
2016-11-13 14:52:25
【UVA10829】 L-Gap Substrings (后缀数组)的更多相关文章
- UVALive - 6869 Repeated Substrings 后缀数组
题目链接: http://acm.hust.edu.cn/vjudge/problem/113725 Repeated Substrings Time Limit: 3000MS 样例 sample ...
- POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数
题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K ...
- POJ1226 Substrings ——后缀数组 or 暴力+strstr()函数 最长公共子串
题目链接:https://vjudge.net/problem/POJ-1226 Substrings Time Limit: 1000MS Memory Limit: 10000K Total ...
- SPOJ - SUBST1 New Distinct Substrings —— 后缀数组 单个字符串的子串个数
题目链接:https://vjudge.net/problem/SPOJ-SUBST1 SUBST1 - New Distinct Substrings #suffix-array-8 Given a ...
- SPOJ- Distinct Substrings(后缀数组&后缀自动机)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- POJ 3415 Common Substrings 后缀数组+并查集
后缀数组,看到网上很多题解都是单调栈,这里提供一个不是单调栈的做法, 首先将两个串 连接起来求height 求完之后按height值从大往小合并. height值代表的是 sa[i]和sa[i ...
- POJ1226:Substrings(后缀数组)
Description You are given a number of case-sensitive strings of alphabetic characters, find the larg ...
- SPOJ DISUBSTR Distinct Substrings 后缀数组
题意:统计母串中包含多少不同的子串 然后这是09年论文<后缀数组——处理字符串的有力工具>中有介绍 公式如下: 原理就是加上新的,减去重的,这题是因为打多校才补的,只能说我是个垃圾 #in ...
- POJ-Common Substrings(后缀数组-长度不小于 k 的公共子串的个数)
题意: 长度不小于 k 的公共子串的个数 分析: 基本思路是计算 A 的所有后缀和 B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于 k 的部分全部加起来. 先将两个字符串连起来,中间 ...
- spoj-694-Distinct Substrings(后缀数组)
题意: 给定一个字符串,求不相同的子串的个数 分析: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同 的 前 缀 的 个 数 . 如 果 所 有 的 后 缀 按 照 suffix ...
随机推荐
- oracle用户管理入门
1.创建一个新用户(普通) create user 用户名 identified by 密码 示例,创建一个名叫小明的用户,密码为xm 2.以管理员的身份给普通用户修改密码(当普通用户忘掉自己的密码时 ...
- MFC/VC++ UI界面美化技术
1. 工具: 1.1设备环境类: Windows下的绘图操作说到底就是DC操作.DC(Device Context设备环境)对象是一个抽象的作图环境,可能是对应屏幕,也可能是对应打印机或其它. ...
- 字符串右移n位(C++实现)
字符串右移n位(C++实现): // ShiftNString.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <i ...
- GUI编程笔记(java)06:GUI窗体添加按钮并对按钮添加事件案例
1.需求:把按钮添加到窗体,并对按钮添加一个点击事件. 步骤: (1)创建窗体对象(2)创建按钮对象(3)把按钮添加到窗体(4)窗体显示 2.编写程序思路: 窗体布局:窗体中组件的排列方式 布局分类 ...
- Eclipse将项目部署tomcat的webapps目录
Eclipse将项目部署tomcat的webapps目录 >>>>>>>>>>>>>>>>>& ...
- c# 前端写代码的情况
<%for(int i=0;i<list_model.Count;i++) { %> <div style=" padding-left:35px;padding-r ...
- C# 的可空合并运算符(??)到底是怎样的宝宝?
前言废语 也怪自己小白和不勤奋,没有系统的学习C#相关的东西,工作一年多还是初级小菜,深感不安,来到园子才发现好多钻研技术的人,也渐渐发现自己开始喜欢上了这个编程的世界.今日偶遇??操作符,发现我只看 ...
- Udacity(优达学城)300块红包优惠券
纳米学位:来自硅谷的名企官方课程 7天免费试用结束后,在"我的教室->设置->纳米学位->续费"页面上的优惠码区域,输入AF55BA53,立即减300元:
- python基础知识五
数据结构基本上就是---它们可以处理一些数据的结构.或者说,它们是用来存储一组相关数据的. python中有三种内建的数据结构---列表.元祖和字典. 我们将会学习如何使用它们,以及它们如何使编程变得 ...
- CSS 创建
当读到一个样式表时,浏览器会根据它来格式化 HTML 文档. 如何插入样式表 插入样式表的方法有三种: 外部样式表 内部样式表 内联样式 外部样式表 当样式需要应用于很多页面时,外部样式表将是理想的选 ...