HDU

来源:互联网 发布:mysql不能删除数据 编辑:程序博客网 时间:2024/06/06 05:56

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6153

题目大意:两个字符串,把第二个串的后缀拿出去和第一个串比,累计次数。

解题思路:首先,先倒转下,把后缀变成前缀,因为只要最长的前缀匹配上,那么比他小的前缀一定能匹配上,所以只要找最长公共前缀,累加答案即可。

AC代码:

#include<cstring>#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;const int MAXN = 1000000 + 5;const int MOD = 1000000000 + 7;int nxt[MAXN], ex[MAXN];char gt1[MAXN], gt2[MAXN];void getNext(char *str){    int i = 0, j, po, len = strlen(str);    nxt[0] = len;    while (str[i] == str[i + 1] && i + 1 < len)        i++;    nxt[1] = i;    po = 1;    for (i = 2;i < len;i++)    {        if (nxt[i - po] + i < nxt[po] + po)            nxt[i] = nxt[i - po];        else        {            j = nxt[po] + po - i;            if (j < 0) j = 0;            while (i + j < len&&str[j] == str[j + i])                j++;            nxt[i] = j;            po = i;        }    }}void exKmp(char *s1, char *s2){    int i = 0, j, po, len = strlen(s1), l2 = strlen(s2);    getNext(s2);    while (s1[i] == s2[i] && i < l2&&i < len)        i++;    ex[0] = i;    po = 0;    for (i = 1;i < len;i++)    {        if (nxt[i - po] + i < ex[po] + po)            ex[i] = nxt[i - po];        else        {            j = ex[po] + po - i;            if (j < 0) j = 0;            while (i + j < len&&j < l2&&s1[j + i] == s2[j])                j++;            ex[i] = j;            po = i;        }    }}int main(){    int t;scanf("%d", &t);    while (t--)    {        LL ans = 0;        scanf("%s%s", gt1, gt2);        reverse(gt1, gt1 + strlen(gt1));        reverse(gt2, gt2 + strlen(gt2));        exKmp(gt1, gt2);        for (int i = 0;i < strlen(gt1);++i)        {            ans += LL(1 + ex[i])*ex[i] / 2 % MOD;            ans %= MOD;        }        printf("%I64d\n", ans);    }    return 0;}
原创粉丝点击