……

51nod——2504 是子序列的个数(一看就会的序列自动机原理)

  还以为序列自动机是什么,写完无意间看到帖子原来这就是序列自动机……这算自己发现算法🐎(雾

  看网上的序列自动机是O(26*len)预处理,O(len)查询,不过用vector和二分查找就可以更快一点了,写起来也比较清楚。

  主要思想就是对于母串,从前往后扫一遍,记录每种(就那26种)字母出现的下标,push_back进vector,这样他们的下标必然升序,也因此可用二分查找去找下标。然后对于子串,也扫一遍,查找子串的每个字母在母串中出现的位置,如果靠后的字母在母串中出现的下标也靠后并且合法,就继续,直到扫完,此串√。

  

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define inf 0x3f3f3f3f
 4 vector<int> id[27];
 5 void init(string s){
 6     int len1=s.length();
 7     for(int i=0;i<len1;i++) id[s[i]-'a'].push_back(i);
 8     for(int i=0;i<27;i++) id[i].push_back(inf);//方便判是否到串尾
 9 }
10 
11 bool searchh(string x){//下一个字母出现的合法位置是cur~串尾
12     int a=x[0]-'a';
13     int cur=id[a][0];
14     if(cur==inf) return 0;
15 
16     cur++;
17     int len2=x.length();
18     for(int i=1;i<len2;i++){
19         int t=x[i]-'a';
20         int tid=*lower_bound(id[t].begin(),id[t].end(),cur);
21         if(tid==inf) return 0;
22         cur=tid+1;
23     }
24     return 1;
25 }
26 int main(){
27     std::ios::sync_with_stdio(0);
28     cin.tie(0);
29     string s; cin>>s;
30     init(s);
31     int n; cin>>n;
32     int ans=0;
33     for(int i=0;i<n;i++){
34         string x; cin>>x;
35         if(searchh(x)) ans++;
36     }
37     cout<<ans<<endl;
38     return 0;
39 }

 

再来个裸题:https://ac.nowcoder.com/acm/contest/392/J

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define inf 0x3f3f3f3f
 4 vector<int> id[27];
 5 void init(string s){
 6     int len1=s.length();
 7     for(int i=0;i<len1;i++) id[s[i]-'a'].push_back(i);
 8     for(int i=0;i<27;i++) id[i].push_back(inf);
 9 }
10 
11 bool searchh(string x){
12     int a=x[0]-'a';
13     int cur=id[a][0];
14     if(cur==inf) return 0;
15 
16     cur++;
17     int len2=x.length();
18     for(int i=1;i<len2;i++){
19         int t=x[i]-'a';
20         int tid=*lower_bound(id[t].begin(),id[t].end(),cur);
21         if(tid==inf) return 0;
22         cur=tid+1;
23     }
24     return 1;
25 }
26 int main(){
27     std::ios::sync_with_stdio(0);
28     cin.tie(0);
29     string s; cin>>s;
30     init(s);
31     int n; cin>>n;
32     for(int i=0;i<n;i++){
33         string x; cin>>x;
34         if(searchh(x)) puts("Yes");
35         else puts("No");
36     }
37     return 0;
38 }

 

posted @ 2019-05-27 20:12  noobimp  阅读(316)  评论(0编辑  收藏  举报