HDU 4644 BWT(Burrows–Wheeler transform+KMP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4644
题意:给出一个串,按照下面的步骤得到一个新串:
(1)首先将其后面增加一个美元符号;
(2)将每个后缀写下,并将前面的补在后面;
(3)排序;
(4)取下最后一列,得到新串。
现在给出新串。再给出一些串,问这些串是不是原串的子串。
思路:首先,我们要做的就是还原原串。下面是题解给出的还原的方法:
乍看上去是O(n^2logn)的!!其实有O(n)还原的方法。不过也是借助于上面的思路。对于上面得到的串gc$aaac为例,首先,为其编号0到6,那么排序后得到为:$aaaccg,编号为2345160(记为W)。我们想一下,以后每次排序得到的W和现在的都是一样的。想想,若首字母不同则显然,小的字母以后还是在前面,比如$开始的这个串一直排名第一;对于相同的字母,比如3个a,那么越靠前的a其后面补的字母越小,还是越靠前。因此,排名第一的串的第一个字母为2=a[0]位置的$;而第一轮补给2位置的为4=a[2]位置的a,第二轮跑到了0位置的串即$的后面。依次类推即可。
之后对于每个查询就是KMP匹配即可。
char s[N],S[N];
int n,a[N];
int cmp(int x,int y)
{
if(s[x]==s[y]) return x<y;
return s[x]<s[y];
}
int next[N];
int cal()
{
next[0]=-1;
int i=0,j=-1;
int len=strlen(s);
while(i<len)
{
if(j==-1||s[i]==s[j]) i++,j++;
else j=next[j];
}
i=0,j=0;
while(i<n)
{
if(j==-1||S[i]==s[j]) i++,j++;
else j=next[j];
if(j==len) return 1;
}
return 0;
}
int main()
{
while(scanf("%s",s)!=-1)
{
n=strlen(s);
int i;
FOR0(i,n) a[i]=i;
sort(a,a+n,cmp);
int t=a[0];
FOR0(i,n)
{
S[i]=s[t];
t=a[t];
}
int m;
RD(m);
while(m--)
{
RD(s);
if(cal()) puts("YES");
else puts("NO");
}
}
}
HDU 4644 BWT(Burrows–Wheeler transform+KMP)的更多相关文章
- HDU 1686 Oulipo (可重叠匹配 KMP)
Oulipo Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- HDU 2087 剪花布条(字符串匹配,KMP)
HDU 2087 剪花布条(字符串匹配,KMP) Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出 ...
- HDU 1686 Oulipo / POJ 3461 Oulipo / SCU 2652 Oulipo (字符串匹配,KMP)
HDU 1686 Oulipo / POJ 3461 Oulipo / SCU 2652 Oulipo (字符串匹配,KMP) Description The French author George ...
- HDU 6311 Cover (无向图最小路径覆盖)
HDU 6311 Cover (无向图最小路径覆盖) Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- HDU 4289 Control (网络流,最大流)
HDU 4289 Control (网络流,最大流) Description You, the head of Department of Security, recently received a ...
- HDU 4292 Food (网络流,最大流)
HDU 4292 Food (网络流,最大流) Description You, a part-time dining service worker in your college's dining ...
- HDU - 3613 Best Reward(manacher或拓展kmp)
传送门:HDU - 3613 题意:给出26个字母的价值,然后给你一个字符串,把它分成两个字符串,字符串是回文串才算价值,求价值最大是多少. 题解:这个题可以用马拉车,也可以用拓展kmp. ①Mana ...
- hdu 4289 Control(最小割 + 拆点)
http://acm.hdu.edu.cn/showproblem.php?pid=4289 Control Time Limit: 2000/1000 MS (Java/Others) Mem ...
- hdu 3308 LCIS(线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3308 LCIS Time Limit: 6000/2000 MS (Java/Others) ...
随机推荐
- 【BZOJ】【2301】problem b
莫比乌斯反演/容斥原理 Orz PoPoQQQ PoPoQQQ莫比乌斯函数讲义第一题. for(i=1;i<=n;i=last+1){ last=min(n/(n/i),m/(m/i)); …… ...
- 3-Highcharts曲线图之显示点值折线图
直接上代码 根据代码注释讲解 <!DOCTYPE> <html lang='en'> <head> <title>3-Highcharts曲线图之显示 ...
- 扫描二维码跳转app
1.判断是否安装了app <html> <head> <meta name="viewport" content="width=device ...
- css内边距与外边距的区别
你真的了解margin吗?你知道margin有什么特性吗?你知道什么是垂直外边距合并?margin在块元素.内联元素中的区别?什么时候该用 padding而不是margin?你知道负margin吗?你 ...
- 简单CSS hack:区分IE6、IE7、IE8、Firefox、Opera
一.跨浏览器的网页设计一直是让人很头疼的问题,这不只是因为浏览器的版本众多,还有一个重要的原因是相同浏览器的不同时期的版本也会有差异,甚至是在不同操作同台上还会有不同.因此使CSS hack技术进行浏 ...
- 13test05:亲密数
/*#include<iostream> using namespace std; int main() {int sum[3000]={0}; for(int i=1;i<3000 ...
- 【五】PHP数组操作函数
1.输出数组的结构:bool print_r(数组); $arr=array('jack','mike','tom'); print_r($arr);//Array ( [0] => jack ...
- POJ 3185
The Water Bowls Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4088 Accepted: 1609 D ...
- POJ 3696 The Luckiest number (欧拉函数,好题)
该题没思路,参考了网上各种题解.... 注意到凡是那种11111..... 22222..... 33333.....之类的序列都可用这个式子来表示:k*(10^x-1)/9进而简化:8 * (10^ ...
- iOS第三方支付-银联支付
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "UPPayPluginDeleg ...