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\n",ans);}}}

版权声明:本文为博主原创文章,,未经博主允许不得转载。

天下无难事,只怕有心人。

HDU 5384 Danganronpa (2015年多校比赛第8场)

相关文章:

你感兴趣的文章:

标签云: