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

字符串·Part 1

时间:2014-12-28 20:42:24      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

字符串算法有哪些呢???Tire,KM,KMP,AC自动机,后缀数组,后缀自动机,RK,Shift-And/Or,Manacher.....

™这么这么多啊!!!

也只能慢慢学了。。。

接下来的题是按我做题顺序来排的,难度的话我就不理了(`?ω?´)

BZOJ 2434: [NOI2011]阿狸的打字机

第一道字符串就做这道简直大丈夫!

先建棵ACTree和FailTree,保存每个字符串的末节点位置。

然后从树根一步一步走,根至当前节点的字符串就是当前打字机内的字符串,一边走一边离线查询。

对于每个查询(x,y)在查到s[y]的末尾节点的时候开始计算,用DFS序思想和树状数组求s[x]的末尾节点的Fail子树中包含了几个s[y]的节点,这就是答案了。

当时AC自动机不会,FailTree不会,后缀数组不会,DFS序没想到。。。QAQ

技术分享
 1 #include <algorithm>
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <vector>
 7 #include <queue>
 8 
 9 #define rep(i, l, r) for(int i = l; i <= r; i++)
10 #define down(i, l, r) for(int i = l; i >= r; i--)
11 #define MS 123456
12 #define MAX 1037471823
13 
14 using namespace std;
15 
16 struct node 
17 { 
18     int x, y, n; 
19     bool operator < (const node &k) const { return x < k.x; };
20 } e[MS]; int ec, fir[MS];
21 int c[MS], r[MS][26], f[MS], h[MS], tc, ss[MS], ds[MS], dt[MS], k[MS];
22 queue<int> p;
23 int n, m, x, y, now, nq;
24 char s[MS];
25 
26 void DFS(int x)
27 {
28     int o = fir[x]; ds[x] = ++now;
29     while (o) { DFS(e[o].y); o = e[o].n; }
30     dt[x] = now;
31 }
32 
33 inline void Add(int x, int z)
34     { int o = x; while (o<=tc+1) k[o]+=z, o = o+(o&(-o));  }
35 
36 inline int Qsum(int x)
37 {
38     int o = x, ans=0; while (o) ans+=k[o], o = o-(o&(-o));  
39     return ans;
40 }
41 
42 inline void Query(int x)
43 {
44     while (e[nq].x == x)
45         { int y=e[nq].y; e[nq].y = Qsum(dt[ss[y]]) - Qsum(ds[ss[y]]-1); nq++; }
46 }
47     
48 int main()
49 {
50     scanf("%s", s); int l=strlen(s); f[0] = -1;
51     rep(i, 0, l-1) 
52         if (s[i]!=P && s[i]!=B) 
53             { if (!r[now][s[i]-a]) tc++, r[now][s[i]-a]=tc, h[tc]=now, c[tc]=s[i]-a; now=r[now][s[i]-a]; }
54         else if (s[i]==P) ss[++n] = now; 
55         else now = h[now];
56     rep(i, 0, tc) f[i] = -1; p.push(0);
57     while (!p.empty())
58     {
59         x = p.front(); p.pop();
60         rep(i, 0, 25) if (r[x][i])
61         {
62             int fo = f[x]; 
63             while (fo >= 0)
64                 { if (r[fo][i]) break; else fo = f[fo]; }
65             if (fo < 0) f[r[x][i]] = 0; else f[r[x][i]] = r[fo][i];
66             p.push(r[x][i]);
67         }
68     }
69     down(i, tc, 1) e[i].y = i, e[i].n = fir[f[i]], fir[f[i]] = i; now = 0; DFS(0);
70     rep(i, 1, tc) fir[i] = 0;
71     scanf("%d", &m);
72     rep(i, 1, m)
73         { scanf("%d%d", &x, &y); e[i].x = y, e[i].y = x, e[i].n = i; }
74     sort(e+1, e+1+m);
75     now=n=0; nq=1; rep(i, 0, l-1) 
76         if (s[i]!=P && s[i]!=B) { now=r[now][s[i]-a]; Add(ds[now], 1); }
77         else if (s[i]==P) Query(++n); else { Add(ds[now], -1); now = h[now]; }
78     rep(i, 1, m) e[i].x = e[i].n; sort(e+1, e+1+m); rep(i, 1, m) printf("%d\n", e[i].y);
79     return 0;
80 }
View Code

 

字符串·Part 1

标签:

原文地址:http://www.cnblogs.com/NanoApe/p/4190320.html

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