题目链接: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)的更多相关文章

  1. HDU 1686 Oulipo (可重叠匹配 KMP)

    Oulipo Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  2. HDU 2087 剪花布条(字符串匹配,KMP)

    HDU 2087 剪花布条(字符串匹配,KMP) Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出 ...

  3. 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 ...

  4. HDU 6311 Cover (无向图最小路径覆盖)

    HDU 6311 Cover (无向图最小路径覆盖) Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...

  5. HDU 4289 Control (网络流,最大流)

    HDU 4289 Control (网络流,最大流) Description You, the head of Department of Security, recently received a ...

  6. HDU 4292 Food (网络流,最大流)

    HDU 4292 Food (网络流,最大流) Description You, a part-time dining service worker in your college's dining ...

  7. HDU - 3613 Best Reward(manacher或拓展kmp)

    传送门:HDU - 3613 题意:给出26个字母的价值,然后给你一个字符串,把它分成两个字符串,字符串是回文串才算价值,求价值最大是多少. 题解:这个题可以用马拉车,也可以用拓展kmp. ①Mana ...

  8. hdu 4289 Control(最小割 + 拆点)

    http://acm.hdu.edu.cn/showproblem.php?pid=4289 Control Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  9. hdu 3308 LCIS(线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3308 LCIS Time Limit: 6000/2000 MS (Java/Others)     ...

随机推荐

  1. 【BZOJ】【2301】problem b

    莫比乌斯反演/容斥原理 Orz PoPoQQQ PoPoQQQ莫比乌斯函数讲义第一题. for(i=1;i<=n;i=last+1){ last=min(n/(n/i),m/(m/i)); …… ...

  2. 3-Highcharts曲线图之显示点值折线图

    直接上代码  根据代码注释讲解 <!DOCTYPE> <html lang='en'> <head> <title>3-Highcharts曲线图之显示 ...

  3. 扫描二维码跳转app

    1.判断是否安装了app <html> <head> <meta name="viewport" content="width=device ...

  4. css内边距与外边距的区别

    你真的了解margin吗?你知道margin有什么特性吗?你知道什么是垂直外边距合并?margin在块元素.内联元素中的区别?什么时候该用 padding而不是margin?你知道负margin吗?你 ...

  5. 简单CSS hack:区分IE6、IE7、IE8、Firefox、Opera

    一.跨浏览器的网页设计一直是让人很头疼的问题,这不只是因为浏览器的版本众多,还有一个重要的原因是相同浏览器的不同时期的版本也会有差异,甚至是在不同操作同台上还会有不同.因此使CSS hack技术进行浏 ...

  6. 13test05:亲密数

    /*#include<iostream> using namespace std; int main() {int sum[3000]={0}; for(int i=1;i<3000 ...

  7. 【五】PHP数组操作函数

    1.输出数组的结构:bool print_r(数组); $arr=array('jack','mike','tom'); print_r($arr);//Array ( [0] => jack ...

  8. POJ 3185

    The Water Bowls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4088   Accepted: 1609 D ...

  9. POJ 3696 The Luckiest number (欧拉函数,好题)

    该题没思路,参考了网上各种题解.... 注意到凡是那种11111..... 22222..... 33333.....之类的序列都可用这个式子来表示:k*(10^x-1)/9进而简化:8 * (10^ ...

  10. iOS第三方支付-银联支付

    #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "UPPayPluginDeleg ...