码迷,mamicode.com
首页 > 其他好文 > 详细

3.3 字符串(1)

时间:2016-08-13 18:09:17      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

Trie 前缀树 字典树  

例题11  LA 3942 http://acm.hust.edu.cn/vjudge/problem/22109

字典树第一个例题我用set水过,先记录这个版本吧,题意是,给一个串,还有一些短串的集合,问有多少种不同的拆分方法使得拆分完后,每个子串都在集合中。

dp[len] 表示前len个有多少拆分法 dp[0]=1, 前0个字符有一种拆分法,空嘛。  dp[len] 就是答案,  转移就是, 如果接下来一段在集合中,那么就可以转移到长度加这段的长度。

 

起点有la=3e5,,对每一个起点,加的串可能有lbi=100,都要枚举,接下来就是判断这个串是否存在,用hash值判,o1,set查询logn ,n=4000, 总体复杂度 la*lb*logn 飘过。

 

技术分享
 1 //#define txtout
 2 //#define debug
 3 #include<bits/stdc++.h>
 4 #define mt(a,b) memset(a,b,sizeof(a))
 5 using namespace std;
 6 typedef long long LL;
 7 const double pi=acos(-1.0);
 8 const double eps=1e-8;
 9 const int inf=0x3f3f3f3f;
10 const int M=3e5+10;
11 const LL MOD=20071027;
12 class String_Hash {///字符串哈希 init O(n) query O(1)
13     typedef unsigned long long typec;///hash 值类型
14     static const int MV=3e5+10;///串长度
15     static const int key=137;///hash 种子值选素数好
16     typec H[MV],xp[MV];
17 public:
18     void init(char s[],int ls) { ///传入串数组和串长
19         H[ls]=0;
20         for(int i=ls-1; i>=0; i--) {
21             H[i]=H[i+1]*key+s[i];
22         }
23         xp[0]=1;
24         for(int i=1; i<=ls; i++) {
25             xp[i]=xp[i-1]*key;
26         }
27     }
28     typec get(int pos,int len) { ///传入初始位置 pos,串长 len,返回串 hash 值
29         return H[pos]-H[pos+len]*xp[len];
30     }
31 }Hash;
32 int n;
33 char a[M];
34 char b[4010][110];
35 LL dp[M];
36 set<unsigned long long> s;
37 int max_len;
38 void init_set() {
39     s.clear();
40     max_len=0;
41     for(int i=0; i<n; i++) {
42         int lb=strlen(b[i]);
43         Hash.init(b[i],lb);
44         s.insert(Hash.get(0,lb));
45         max_len=max(max_len,lb);
46     }
47 }
48 LL solve() {
49     init_set();
50     int len=strlen(a);
51     for(int i=0; i<=len; i++) {
52         dp[i]=0;
53     }
54     dp[0]=1;
55     Hash.init(a,strlen(a));
56     for(int i=0; i<len; i++) {
57         if(dp[i]==0) continue;
58         for(int j=0; j<max_len; j++) {
59             if(!s.count(Hash.get(i,j+1))) continue;
60             dp[i+j+1]+=dp[i];
61             dp[i+j+1]%=MOD;
62         }
63     }
64     return dp[len];
65 }
66 int main() {
67 #ifdef txtout
68     freopen("in.txt","r",stdin);
69     freopen("out.txt","w",stdout);
70 #endif // txtout
71     int cas=1;
72     while(~scanf("%s%d",a,&n)) {
73         for(int i=0; i<n; i++) {
74             scanf("%s",b[i]);
75         }
76         printf("Case %d: %lld\n",cas++,solve());
77     }
78     return 0;
79 }
View Code

 

 

 

end

3.3 字符串(1)

标签:

原文地址:http://www.cnblogs.com/gaolzzxin/p/5768391.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!