zoukankan      html  css  js  c++  java
  • HDU 5384 Danganronpa (2015年多校比赛第8场)

    1.题目描写叙述:点击打开链接

    2.解题思路:本题利用字典树解决。本题要求查找全部的B[j]在A[i]中出现的总次数。那么我们能够建立一颗字典树,将全部的B[j]插入字典树,因为一个串的全部字串相当于它全部后缀的前缀。

    因此在查找时候,仅仅须要查找A[i]的每个后缀就可以,然后累加这个后缀的前缀个数,就可以得到该后缀中子串的个数。全部后缀的值相加,就是终于的答案。

    3.代码:

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<algorithm>
    #include<cassert>
    #include<string>
    #include<sstream>
    #include<set>
    #include<vector>
    #include<stack>
    #include<map>
    #include<queue>
    #include<deque>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<functional>
    using namespace std;
    
    typedef long long ll;
    typedef unsigned int uint;
    typedef unsigned long long ull;
    typedef pair <int, int> P;
    
    const int N=100000+10;
    int n,m;
    char A[N][10005];
    char B[N];
    struct Trie
    {
        int tree[N][26],val[N],cnt;
        Trie()
        {
            init();
        }
        void init()
        {
            cnt=1;
            memset(tree,0,sizeof(tree));
        }
        void insert(char*s)
        {
            int p=0,l=strlen(s);
            for(int i=0;i<l;i++)
            {
                int a=s[i]-'a';
                if(!tree[p][a])
                {
                    val[cnt]=0;
                    tree[p][a]=cnt++;
                }
                p=tree[p][a];
            }
            ++val[p];
        }
    
        int query(char*s)
        {
            int p=0,l=strlen(s),ans=0;
            for(int i=0;i<l;i++)
            {
                int a=s[i]-'a';
                if(!tree[p][a])return ans;
                p=tree[p][a];
                ans+=val[p];
            }
            return ans;
        }
    }T;
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            T.init();
            for(int i=0;i<n;i++)
                scanf("%s",A[i]);
            ll ans;
            for(int i=0;i<m;i++)
            {
                scanf("%s",B);
                T.insert(B);//将全部的B[j]插入字典树
            }
            for(int i=0;i<n;i++)
            {
                ans=0;
                int l=strlen(A[i]);
                for(int j=0;j<l;j++)
                ans+=T.query(A[i]+j);//枚举后缀的前缀在字典树中出现多少次,得到该后缀的返回值,累加就是答案
                printf("%I64d
    ",ans);
            }
        }
    }
    
    
    
    

  • 相关阅读:
    C#进阶-Linq-join
    C#进阶-Linq
    C#-string-stringBuilder
    C#-继承-多态
    Spring基础
    JQuery基本操作
    Oracle数据库基础操作
    AJAX前端后端
    AJAX异步提交(前端)
    js基本操作
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6812863.html
Copyright © 2011-2022 走看看