大白皮上面把Trie树写在了结构体里面,这样好像直接就限制了ch[][]的范围,应该不是以堆的形式来存了。其实完全不需要,看了上面的解释就知道了,不过感觉还是直接定义一个Trie结构体比较好看一点。。。(然而并没有什么卵用)。就用大白皮上面的那道LA_3942为例吧。下面是代码。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define FOR(i,x,y) for(int i = x;i < y;i ++) #define IFOR(i,x,y) for(int i = x;i > y;i --) #define MOD 20071027 using namespace std; int ch[4005*105][26],sz,val[4005*105],len[300005],cnt; int dp[300005]; char s[300005]; void init(){ memset(ch[0],0,sizeof(ch[0])); sz = 1; } void insert(char* str,int v){ int n = strlen(str),u = 0; FOR(i,0,n){ int c = str[i] - 'a'; if(!ch[u][c]){ memset(ch[sz],0,sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; } void find(char* str){ cnt = 0; int n = strlen(str),u = 0; FOR(i,0,n){ int c = str[i] - 'a'; if(!ch[u][c]) return; int id = ch[u][c]; if(val[id]) len[cnt++] = (i+1); u = id; } return ; } int main(){ //freopen("test.in","r",stdin); int tCase = 0; while(~scanf("%s",s)){ printf("Case %d: ",++tCase); init(); int n; char str[105]; scanf("%d",&n); while(n--){ scanf("%s",str); insert(str,-1); } n = strlen(s); dp[n] = 1; IFOR(i,n-1,-1){ find(s+i); dp[i] = 0; FOR(j,0,cnt){ dp[i] += dp[i+len[j]]; dp[i] %= MOD; } } printf("%d ",dp[0]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。