2534: Uva10829L-gap字符串

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 177  Solved: 66
[Submit][Status][Discuss]

Description

有一种形如uvu形式的字符串,其中u是非空字符串,且V的长度正好为L,那么称这个字符串为L-Gap字符串 
给出一个字符串S,以及一个正整数L,问S中有多少个L-Gap子串.

Input

第一行一个数字L 
第二行一个字符串S

Output

一个数字表示S中有多少个L-Gap子串.

Sample Input

3
aabbaa

Sample Output

2

Hint
S的长度不超过50000,L<=10

HINT

 

Source

【题意】

  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的。

这道题我看了100遍!!

现在又明白了一点了ORZ。。。分块屌ORZ。。。

好吧,是按照u的长度分块!!

为什么呢,目的是:答案串的u至少包含一个分割点(上面的蓝色突起)

我们对于其包含的第一个分割点时计算他!!!(就是上面红色圈起的部分)

如果匹配长度越过第二个分割点,那么是会重复计算的,所以在这一题,向前匹配和向后匹配都可以直接while,越过分割点的时候就结束。

ORZ。。。                                                                                                                       (转载自Konjakmoyu)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e5+;
typedef long long ll;
int n,T,L,cas,c[N],h[N],sa[N],tsa[N],rank[N],trank[N];
int log2[N],f[N][];
char s[N];
void DA(int maxx=){
int p;
for(int i=;i<=maxx;i++) c[i]=;
for(int i=;i<=n;i++) c[rank[i]=s[i]]++;
for(int i=;i<=maxx;i++) c[i]+=c[i-];
for(int i=n;i;i--) sa[c[rank[i]]--]=i;
trank[sa[]]=p=;
for(int i=;i<=n;i++){
if(rank[sa[i]]!=rank[sa[i-]]) p++;
trank[sa[i]]=p;
}
for(int i=;i<=n;i++) rank[i]=trank[i];
for(int k=;p<n;k<<=,maxx=p){
p=;
for(int i=n-k+;i<=n;i++) tsa[++p]=i;
for(int i=;i<=n;i++) if(sa[i]>k) tsa[++p]=sa[i]-k;
for(int i=;i<=maxx;i++) c[i]=;
for(int i=;i<=n;i++) trank[i]=rank[tsa[i]];
for(int i=;i<=n;i++) c[trank[i]]++;
for(int i=;i<=maxx;i++) c[i]+=c[i-];
for(int i=n;i;i--) sa[c[trank[i]]--]=tsa[i];
trank[sa[]]=p=;
for(int i=;i<=n;i++){
if(rank[sa[i]]!=rank[sa[i-]]||rank[sa[i]+k]!=rank[sa[i-]+k]) p++;
trank[sa[i]]=p;
}
for(int i=;i<=n;i++) rank[i]=trank[i];
}
for(int i=,k=;i<=n;i++){
int j=sa[rank[i]-];
while(s[i+k]==s[j+k]) k++;
h[rank[i]]=k;if(k>) k--;
}
}
void RMQ(){
for(int i=;i<=n;i++) f[i][]=h[i];
for(int i=;i<=n;i++) log2[i]=log2[i>>]+;
for(int j=;j<=log2[n];j++){
for(int i=;i+(<<j)-<=n;i++){
f[i][j]=min(f[i][j-],f[i+(<<j-)][j-]);
}
}
}
int query(int l,int r){
int a=rank[l],b=rank[r];
if(a>b) swap(a,b);
a++;
int k=log2[b-a+];
return min(f[a][k],f[b-(<<k)+][k]);
}
int main(){
scanf("%d%s",&L,s+);n=strlen(s+);
DA();RMQ();
ll ans=;
for(int len=,now,x,y,z;len<=n;len++){
for(int i=;i<=n/len;i++){
now=len*i+;y=;
if(s[now]!=s[now+L+len]||now+L+len>n) continue;
x=min(len,query(now,now+L+len));
while(s[now-y-]==s[now+L+len-y-]&&y+<len) y++;
if(x+y-len+>) ans+=(ll)(x+y-len+);
}
}
printf("%lld\n",ans);
return ;
}

ps:UVA上rank是关键字。(然后不用std空间就好了或改一下变量名)

代码:UVA - 10829

2534: Uva10829L-gap字符串的更多相关文章

  1. 「BZOJ 2534」 L - gap字符串

    「BZOJ 2534」 L - gap字符串 题目描述 有一种形如 \(uv u\) 形式的字符串,其中 \(u\) 是非空字符串,且 \(v\) 的长度正好为 \(L\), 那么称这个字符串为 \( ...

  2. 【BZOJ 2534】Uva10829L-gap字符串

    [链接]h在这里写链接 [题意]     让你找出uvu形式的字符串个数.     v非空且长度为L,且u也非空 [题解]     之前做过一道相同的题.     枚举u的长度.     然后从u,2 ...

  3. 转:C语言字符串操作函数 - strcpy、strcmp、strcat、反转、回文

    转自:C语言字符串操作函数 - strcpy.strcmp.strcat.反转.回文 C++常用库函数atoi,itoa,strcpy,strcmp的实现 作者:jcsu C语言字符串操作函数 1. ...

  4. JSON字符串转换成JSON对象

    字符串转对象(strJSON代表json字符串) var obj = eval(strJSON); var obj = strJSON.parseJSON(); var obj = JSON.pars ...

  5. 字符串hash函数

    本文搜集了一些字符串的常用hash函数. 范例1:判断两个单词是否含有相同的字母,此时我们可以用hash做.例如,“aaabb”与"aabb"含有相同的单词.(参考:http:// ...

  6. 第一百二十七节,JavaScript,JSON数据类型转换,数据转换成字符串,字符串转换成数据

    第一百二十七节,JavaScript,JSON数据类型转换,数据转换成字符串,字符串转换成数据 学习要点: 1.JSON语法 2.解析和序列化 前两章我们探讨了XML的结构化数据,但开发人员还是觉得这 ...

  7. Binary Gap(二进制空白)

    中文标题[二进制空白] 英文描述 A binary gap within a positive integer N is any maximal sequence of consecutive zer ...

  8. BWT转换对字符串进行编码

    今天看了下bowtie 的论文, 里面描述了BWT转换的过程和bowtie的比对算法: NGS测序数据的数据量非常大, 为了更快的处理, 通常需要对数据进行压缩:而BWT实际上就是一种数据转换方法, ...

  9. 清北学堂学习总结 day2 字符串 练习

    1.hash表(哈希表) codevs 2147 数星星--简单哈希  时间限制: 3 s  空间限制: 64000 KB  题目等级 : 钻石 Diamond 题目描述 Description 小明 ...

随机推荐

  1. 织梦dedecms dede plus文件作用介绍及安全设置

    一.安装设置 1.默认的后台模块中心有很多模块. 这里除了"友情链接"模块其他都可以删掉.在后台可以先卸载再删除. 2.如果是一开始就不想要的话,安装版plus目录下进行如下操作. ...

  2. Bootstrap-学习系列

    前言 首先在此多谢博友们在前几篇博文当中给与的支持和鼓励,以及在回复中提出的问题.意见和看法. 在此先声明一下,之前在下小菜所有的随笔文章中,只有前两篇关于Bootstrap的文章发表在了博客园的首页 ...

  3. sql server使用sql插入中文字符串乱码问题

    在插入语句前加N就行了 sb.Append(string.Format("update chapter set [content]=N'{0}' where Id ={1} ;", ...

  4. windows服务器详细安全设置

    1).系统安全基本设置 1.安装说明:系统全部NTFS格式化,重新安装系统(采用原版win2003),安装杀毒软件(Mcafee),并将杀毒软件更新,安装sp2补钉,安装IIS(只安装必须的组件),安 ...

  5. U3D Debug.DrawRay

    Debug.DrawRay第二个参数方向,事实上需要手动输入长度.并且不是无限长的射线,是根据方向的长度来的 如果参数不指定颜色,绘制出来的就是白色

  6. C#多线程方法同步

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  7. 品茗论道说广播(Broadcast内部机制讲解)(上)

    1 概述 我们在编写Android程序时,常常会用到广播(Broadcast)机制.从易用性的角度来说,使用广播是非常简单的.不过,这个不是本文关心的重点,我们希望探索得再深入一点儿.我想,许多人也不 ...

  8. 1.文件I/O

    一. open()&close() #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h& ...

  9. Unix系统编程(二)open的练习

    在上一篇中学习了一下open函数的基本用法,这里就要练习一下.计算机就是要实践嘛. 用open创建一个文件 #include <sys/types.h> #include <sys/ ...

  10. (转)64位开源处理器Rocket的源代码简单介绍

    转载地址: http://blog.csdn.net/leishangwen/article/details/46604819 最近大概阅读了一下UCB发布的Rocket处理器的源码,对源代码各个文件 ...