HDU 6096 String (字典树, 2017 Multi-Univ Training Contest 6)

来源:互联网 发布:数据库信息如何填写 编辑:程序博客网 时间:2024/05/22 06:43

Problem

有 N 组单词 Wi ,以及 Q 组前缀 Pi ,后缀 Si 。求对于每组前后缀,能匹配多少单词。

Idea

利用字典树解决。将前缀与后缀拼接形成 Pi++reverse(Si) 。并离线将全部询问加入字典树中,在最后一个节点位置标记上该点标号。

枚举每个单词,查找单词在字典树上能有多少的匹配情况。具体为:优先匹配 Wi 在字典树的前缀,当有某点的后继节点存在 拼接符 ,则倒置 Wi 开始匹配后缀,对找到的每个标记 ++ 。

Code

#include<bits/stdc++.h>using namespace std;const int N = 500000 + 10;int T, n, Q, st[N], len[N], pot[N], ans[N];char s[N], pre[N], suf[N], combin[N];const int Node_max = 1000000 + 5;struct Node{    int next[30], flag;} Trie[Node_max];int Tsize;int Trie_insert(char str[], int st, int len, int idx){    int tmp = 0;    for(int i=st;i<st+len;i++) {        if(!Trie[tmp].next[str[i] - 'a']) {            Trie[tmp].next[str[i] - 'a'] = ++Tsize;        }        tmp = Trie[tmp].next[str[i]-'a'];    }    if(Trie[tmp].flag == 0) Trie[tmp].flag = idx;    return Trie[tmp].flag;}void Trie_query_suf(int it, int st, int en) {    for(int i=en;i>=st;i--) {        if(Trie[it].next[s[i] - 'a'] == 0)  return;        it = Trie[it].next[ s[i] - 'a' ];        if(Trie[it].flag)   ans[ Trie[it].flag ]++;    }}void Trie_query_pre(int it, int st, int en) {    for(int i=st;i<=en;i++) {        if(Trie[it].next[26])   Trie_query_suf(Trie[it].next[26], i, en);        if(Trie[it].next[ s[i] - 'a' ] == 0)    return;        it = Trie[it].next[ s[i] - 'a' ];    }}int main(){    scanf("%d", &T);    while(T-- && scanf("%d %d", &n, &Q)!=EOF)    {        memset(Trie, 0, sizeof(Trie));        memset(ans, 0, sizeof(ans));        Tsize = 0;        int ip = 0;        for(int i=1;i<=n;i++) {            scanf(" %s", s+ip);            st[i] = ip;            len[i] = strlen(s+ip);              ip += len[i];        }        for(int i=1;i<=Q;i++) {            scanf(" %s %s", pre, suf);            int qlen = 0;            for(;pre[ qlen ];qlen++)                combin[qlen] = pre[qlen];            combin[qlen++] = char('z'+1);            for(int j=strlen(suf)-1;j>=0;j--)                combin[qlen++] = suf[j];            combin[qlen] = '\0';            pot[i] = Trie_insert(combin, 0, qlen, i);           }        for(int i=1;i<=n;i++) {            Trie_query_pre(0, st[i], st[i]+len[i]-1);        }        for(int i=1;i<=Q;i++) {            if(pot[i] != i) ans[i] = ans[ pot[i] ];            printf("%d\n", ans[i]);        }    }}
阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝竖着抱早了怎么办 孕妇吃的水果少怎么办 6个月宝宝厌奶怎么办 5个月宝宝厌奶怎么办 11个月宝宝厌奶怎么办 母乳宝宝不喝奶粉怎么办 换奶粉不拉大便怎么办 宝宝和妈妈不亲怎么办 冬天榨果汁太凉怎么办 四个月宝宝拉水怎么办 婴儿吃奶吃撑了怎么办 1岁的宝宝腹泻怎么办 一岁宝宝老拉肚子怎么办 一岁宝宝拉肚子怎么办啊 小孩发烧怎么办39度要吃消炎药吗 孩子不爱吃水果蔬菜怎么办 一岁宝宝不吃水果怎么办 一岁宝宝不爱吃水果怎么办 1岁多宝宝不吃水果怎么办 中学生不爱与家长交流怎么办 孩子一直37度多怎么办 小孩39度3算高烧怎么办 7岁发烧怎么办如何退烧 7岁反复发烧7天怎么办 一岁发烧39.8度怎么办 反复发烧39度4天怎么办 大人发烧到39度怎么办 小孩高烧39度多怎么办 孩子嗓子发炎发烧怎么办吃什么药 猫咪吃了点桃子怎么办 猫吃了牛油果怎么办 苹果手机死机开不了机怎么办 新生儿出生第一天没奶水怎么办 第一天断奶奶水一直流出怎么办 3岁宝宝不长个子怎么办 5个月宝宝不长个怎么办 孩子比同龄人矮很多怎么办 孕妇做春梦宫缩怎么办 减肥掉头发很厉害怎么办 孕妇吃了金枪鱼罐头怎么办 怀孕吃了烂水果怎么办