字符串·Part 1

字符串算法有哪些呢???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 }

时间: 2024-11-04 18:57:50

字符串·Part 1的相关文章

条件、循环、函数定义、字符串操作练习

注意标准库的两种导入与使用方式,建议大家采用<库名>.<函数名>的方式. 对前面的代码进行优化,用for,while,if,def实现: 用循环画五角星 1 import turtle 2 3 turtle.fillcolor("red") 4 turtle.begin_fill() 5 for i in range(5): 6 turtle.forward(100) 7 turtle.right(144) 8 turtle.end_fill() 用循环画同心圆

sql常用格式化函数及字符串函数

一.常用格式化函数 1.日期转字符串 select to_char(current_timestamp, 'YYYY-MM-DD HH24:MI:SS') //2017-09-18 22:41:50 YYYY:年(4和更多位) MM:月份号(01-12) DD:一个月里的日(01-31) HH24:一天的小时数(00-23) MI:分钟(00-59) SS:秒(00-59) 2.字符串转日期 select to_date('2017-09-18','YYYY-MM-DD') //2017-09-

PHP 格式化字符串sprintf()

字符串函数 sprintf() 函数把格式化的字符串写入一个变量中 函数说明:sprintf(格式, 要转换的字符串)  参考PHP手册 返回: 格式化后的字符串 举例: 如:保留2位小数, $str = '99.9';echo sprintf('%01.2f', $str);结果为:99.90 echo round($str, 2); 结果为:99.9

js中字符串的替换

定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串. 语法 stringObject.replace(regexp/substr,replacement)参数 描述 regexp/substr 必需.规定子字符串或要替换的模式的 RegExp 对象. 请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象. replacement 必需.一个字符串值.规定了替换文本或生成替换文本的函数. 返

数组、字符串、集合

数组与集合的转换.数组与字符串的转换 ========数组变集合 String[] arr = {"abc","cc","kkkk"}; //把数组变成list集合有什么好处? /* 可以使用集合的思想和方法来操作数组中的元素. 注意:将数组变成集合,不可以使用集合的增删方法. 因为数组的长度是固定. contains. get indexOf() subList(); 如果你增删.那么会产生UnsupportedOperationExcepti

《Java编程思想》第十三章 字符串

<Java编程思想>读书笔记 1.String作为方法的参数时,会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置,从未动过. 2.显式地创建StringBuilder允许预先为他指定大小.如果知道字符串多长,可以预先指定StringBuilder的大小避免多次重新分配的冲突. 1 /** 2 * @author zlz099: 3 * @version 创建时间:2017年9月1日 下午4:03:59 4 */ 5 public class UsingStringBuilder {

SpringMVC后台使用对象接受参数字符串转日期

在springMVC配置文件中加入: <bean id="dateConvert" class="com.iomp.util.DateConvert"/> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property

python判断字符串,str函数isdigit、isdecimal、isnumeric的区别

s为字符串s.isalnum() 所有字符都是数字或者字母s.isalpha() 所有字符都是字母s.isdigit() 所有字符都是数字s.islower() 所有字符都是小写s.isupper() 所有字符都是大写s.istitle() 所有单词都是首字母大写,像标题s.isspace() 所有字符都是空白字符.\t.\n.\r 判断是整数还是浮点数a=123b=123.123 >>>isinstance(a,int)True>>>isinstance(b,floa

【自动化__持续集成】___java___字符串转数组

一.代码如下 package www.wujianbotwo; public class Demo08 { public static void main(String[] args) { // TODO Auto-generated method stub String content= "wujianbo,wujianob,33333"; String[] ud= content.split(",");//将字符串分段成一个数组 for(int i=0; i&l

字符串的模式匹配中的算法

字符串的模式匹配是一个比较经典的问题:假设有一个字符串S,称其为主串,然后还有一个字符串T,称其为子串. 现在要做的是,从主串S当中查找子串T的位置,如果存在返回位置值,如果不存在返回-1.另外主串又称为目标串, 子串称为模式串. 暴力匹配算法 这是一个经典的串匹配问题,涉及的算法也比较多,先讨论第一种简单的暴力算法,思路如下 将主串S的第pos个字符 与 子串T的第一个字符比较, 若相同,继续比较子串和主串后面的字符. 若不相同,那么从主串S的第(pos + 1)个字符开始继续向后匹配,直到匹