[HDU 5507] GT and strings

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

题目大意: 给你n个串, q次询问(x, y), x是否为y的子序列, x是否为y的子串。( n,q,105

思路:这题数据好像很水, 整个差不多就是在打暴力, 时间复杂度什么的都不知道扔到哪去了。

关于x是否为y的子序列。 预处理f[i][j]表示从i往后第一个字符为’a’+j的位置。 每次询问用f数组让x在y上跳, 跳出去了为0。

关于x是否为y的子串。 先将n个串建立一个ac自动机。 对于所有询问的y串, 在ac自动机上跑, 记录y所能到的所有有结束标记的节点, 算上fail链。 可以用map存起来。 每次询问O(logn)直接回答。

#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define pi pair<int, int >
#define mk(i, j) make_pair(i, j)

using namespace std;

const int N = (int)1e5 + 10;

int n, q, E[N][2], ask[N], tim;
char str[N]; int st[N], ed[N], f[N][26];

map<pi, bool > M;

struct ACM{
    int cnt, rt, ch[N][26], fail[N], lst[N], edd[N], pre[N], fa[N];
    void init(){
        cnt = 0; memset(ch[0], 0, sizeof(ch[0])); 
    }
    int NewNode(){
        cnt ++; fail[cnt] = fa[cnt] = pre[cnt] = lst[cnt] = 0;
        memset(ch[cnt], 0, sizeof(ch[cnt]));
        return cnt;
    }
    void insert(int id){
        int p = rt;
        for (int i = st[id]; i <= ed[id]; i ++){
            int j = str[i] - 'a';
            if (!ch[p][j]) ch[p][j] = NewNode(), pre[cnt] = j, fa[cnt] = p;
            p = ch[p][j];
        }
        edd[id] = p; lst[p] = 1;
    }
    int head, tail, que[N];
    void call_fail(){
        head = tail = 0;
        que[tail = 1] = rt;
        while (head < tail){
            int u = que[++ head];
            for (int j = 0; j < 26; j ++)
                if (ch[u][j]) que[++ tail] = ch[u][j];
            int p = fa[u];
            while (u != rt && p != rt && !ch[fail[p]][pre[u]]) p = fail[p];
            if (p == rt) continue;
            fail[u] = ch[fail[p]][pre[u]];
        }
    }
    void find(int id){
        int u = rt;
        for (int i = st[id]; i <= ed[id]; i ++){
            int j = str[i] - 'a'; u = ch[u][j];
            for (int p = u; p; p = fail[p]){
                if (lst[p]){
                    M[mk(p, id)] = 1;
                }
                if (!lst[fail[p]]) fail[p] = fail[fail[p]];
            }
        }
    }
}acm;

int subsequence(int x, int y){
    int p = st[y];
    for (int i = st[x]; i <= ed[x]; i ++){
        p = f[p][str[i] - 'a'];
        if (p > ed[y]) return 0;
        p ++;
    }
    return 1;
}
int substring(int x, int y){
    return M[mk(acm.edd[x], y)];
}

int main(){

    int T; scanf("%d", &T);
    while (T --){
        scanf("%d %d", &n, &q);
        for (int i = 1; i <= n; i ++){
            st[i] = ed[i - 1] + 1;
            scanf("%s", str + st[i]);
            ed[i] = strlen(str + st[i]) + ed[i - 1];
        }

        for (int i = 0; i < 26; i ++) f[ed[n] + 1][i] = ed[n] + 1;
        for (int i = ed[n]; i >= 1; i --)
            for (int j = 0; j < 26; j ++)
                if (str[i] == 'a' + j) f[i][j] = i;
                else f[i][j] = f[i + 1][j];

        acm.init(); M.clear();
        for (int i = 1; i <= n; i ++) acm.insert(i);
        acm.call_fail();

        tim ++;
        for (int i = 1; i <= q; i ++){
            scanf("%d %d", E[i] + 0, E[i] + 1);
            ask[E[i][1]] = tim;
        }

        for (int i = 1; i <= n; i ++) if (ask[i] == tim) acm.find(i);

        for (int i = 1; i <= q; i ++) printf("%d%d", subsequence(E[i][0], E[i][1]), substring(E[i][0], E[i][1]));

        puts("");
    }

    return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值