字符串

Tags:Noip前的大抱佛脚

经验

用FFT求解字符串匹配问题

  • 一一对应

把其中一个\(Reverse\)后,对于每个字符跑一遍FFT,打上\(Tag\)

如果在某个位置上有串长个\(Tag\)那便是匹配上了一处

  • 模糊匹配

\(Fuzzy Search\) 在跑\(FFT\)前把模糊门限值的区间内全部置为1,然后同样的操作

两(多)串DP时状态合并

插入AC自动机,老套路了

最长公共子序列转LIS

求两个串的最长公共子序列,把第二个串的每个值映射到第一个串上 该值的位置

然后对第二个串求LIS即可(最长公共子串就是第二个串的最长连续段)

位运算最大值

异或最大值:建Trie贪心

与最大值:建Trie贪心(1的儿子siz大于2则走)/高维前缀和逐位贪心

或最大值:高维前缀和逐位贪心

但是求(x+B)^A的最大值呢(SCOI2016美味)(当然&操作也是一样的,这种题通常值域很小)

同样贪心地做

开值域线段树,贪心到某一位,需要该位为0或者1,则对应地可以算出x的范围,查询是否有在这个范围之内的x即可

挂链哈希

期望\(O(1)\),当然支持查询多个关键字

const int Mo=YYB;
struct HashTable
{
struct Line{int next,val;}a[Mo];
int head[Mo],cnt;
void reset() {memset(head,0,sizeof(head));cnt=0;}
void Add(int p,int val) {a[++cnt]=(Line){head[p],val};head[p]=cnt;}
int Query(int x)
{
for(int i=head[x%Mo];i;i=a[i].next)
if(a[i].val==x) return 1;return 0;
}
}Hash;

哈希处理回文串

正反哈希前缀和即可求出区间哈希值,然后查询起点到回文中心的正哈希和回文中心到终点的反哈希即可

树哈希

例:一棵无根树的本质不同的独立集个数(\(k\)棵相同子树方案为\(x\)则乘一个可重组合)

字符串模板库

KMP

【模板】KMP字符串匹配

用于两串匹配问题,做法是对子串求next后匹配母串,复杂度\(O(n+m)\)

const int N=1e6+10;
char s1[N],s2[N];
int nxt[N];
int main()
{
scanf("%s%s",s1+1,s2+1);
int l1=strlen(s1+1),l2=strlen(s2+1);
for(int i=2;i<=l2;i++)
{
int j=nxt[i-1];
while(j&&s2[j+1]!=s2[i]) j=nxt[j];
nxt[i]=(s2[j+1]==s2[i])+j;
}
for(int i=1,j=0;i<=l1;i++)
{
while(j&&s2[j+1]!=s1[i]) j=nxt[j];
if(s2[j+1]==s1[i]) j++;
if(j==l2) printf("%d\n",i-l2+1),j=nxt[j];
}
for(int i=1;i<=l2;i++) printf("%d ",nxt[i]);
return puts(""),0;
}

最小循环表示

工艺

\(O(n)\)求一个环从某点断开按一定方向形成的字典序最小的链

int i,j=2,k,l,p,s[610000];
int main()
{
cin>>l;for(i=1;i<=l;i++) cin>>s[i],s[i+l]=s[i];
for(i=1;j<=l&&i<=l&&k<=l;)
{
if(s[i+k]==s[j+k]) {k++;continue;}
s[i+k]<s[j+k]?j+=k+1:i+=k+1;
if(i==j) i++;k=0;
}
for(;p<l;p++) cout<<s[min(i,j)+p]<<" ";
}

Mancher

【模板】manacher算法

求出以每个位置为中心的最长回文串,复杂度\(O(n)\),证明:每次操作要么不动\(while\),要么给两个单调的指针至少\(+1\)


const int N=3e7+10;
char s[N],t[N];
int l,p[N],R,C,Ans;
int main()
{
scanf("%s",t+1);
for(int i=1,len=strlen(t+1);i<=len;i++)
s[++l]='#',s[++l]=t[i];s[++l]='#';
for(int i=1;i<=l;i++)
{
p[i]=i<=R?min(p[C*2-i],R-i):1;
while(s[i+p[i]]==s[i-p[i]]&&i+p[i]<=l&&i-p[i]>=1) p[i]++;
if(i+p[i]-1>R) R=i+p[i]-1,C=i;
Ans=max(Ans,p[i]-1);
}
cout<<Ans<<endl;
}

AC自动机

【模板】AC自动机(加强版)

用于处理多串匹配单串等多串问题,复杂度\(O(n*26)\)

方式是先建\(Trie\),求出\(fail\)指针后建成\(Trie\)图

int n,node,fail[N],ch[N][26];
queue<int> Q;
void Insert(char *s,int id)
{
int x=0,l=strlen(s+1);
for(int i=1;i<=l;i++)
{
int &p=ch[x][s[i]-'a'];
if(!p) p=++node;x=p;
}
}
void Get_fail()
{
for(int i=0;i<26;i++) if(ch[0][i]) Q.push(ch[0][i]);
while(!Q.empty())
{
int x=Q.front();Q.pop();
for(int i=0;i<26;i++)
if(ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],Q.push(ch[x][i]);
else ch[x][i]=ch[fail[x]][i];
}
}

后缀数组

【模板】后缀排序

用于处理字符串后缀的东西(不过这东西Noip不会考,省选题倒是经常出现)

复杂度\(O(nlogn)\),基于一种倍增和桶排的思想对后缀排序


const int N=1e6+10;
int m=300,t[N],x[N],y[N],rk[N],h[N],SA[N],l;char s[N];
int cmp(int i,int j,int k) {return y[i]==y[j]&&y[i+k]==y[j+k];}
void Sort()
{
for(int i=1;i<=m;i++) t[i]=0;
for(int i=1;i<=l;i++) t[x[i]]++;
for(int i=1;i<=m;i++) t[i]+=t[i-1];
for(int i=l;i>=1;i--) SA[t[x[y[i]]]--]=y[i];
}
void Get_SA()
{
for(int i=1;i<=l;i++) x[i]=s[i],y[i]=i;Sort();
for(int k=1,p=0;k<=l;k<<=1)
{
for(int i=l-k+1;i<=l;i++) y[++p]=i;
for(int i=1;i<=l;i++) if(SA[i]>k) y[++p]=SA[i]-k;
Sort();swap(x,y);x[SA[1]]=p=1;
for(int i=2;i<=l;i++) x[SA[i]]=cmp(SA[i],SA[i-1],k)?p:++p;
if(p==l) break;m=p;p=0;
}
for(int i=1;i<=l;i++) rk[SA[i]]=i;
for(int i=1,j=0;i<=l;i++)
{
while(s[i+j]==s[SA[rk[i]-1]+j]) j++;
h[rk[i]]=j;if(j) j--;
}
}
int main()
{
scanf("%s",s+1);l=strlen(s+1);Get_SA();
for(int i=1;i<=l;i++) printf("%d ",SA[i]);
}

后缀自动机

【模板】后缀自动机

用于处理子串的问题。这家伙比SA好写复杂度还优秀适用范围还广些

不过Noip还是不会考,复杂度\(O(n)\)


const int N=2e6+10;
int l,lst=1,node=1,t[N],A[N],len[N],fa[N];
int ch[N][26],siz[N];char s[N];
void Extend(int c)
{
int f=lst,p=++node;lst=p;
len[p]=len[f]+1;siz[p]=1;
while(f&&!ch[f][c]) ch[f][c]=p,f=fa[f];
if(!f) {fa[p]=1;return;}
int x=ch[f][c],y=++node;
if(len[f]+1==len[x]) {fa[p]=x;node--;return;}
len[y]=len[f]+1;fa[y]=fa[x];fa[x]=fa[p]=y;
memcpy(ch[y],ch[x],sizeof(ch[y]));
while(f&&ch[f][c]==x) ch[f][c]=y,f=fa[f];
}
int main()
{
scanf("%s",s+1);l=strlen(s+1);
for(int i=1;i<=l;i++) Extend(s[i]-'a');
}

Noip前的大抱佛脚----字符串的更多相关文章

  1. Noip前的大抱佛脚----文章索引

    Noip前的大抱佛脚----赛前任务 Noip前的大抱佛脚----考场配置 Noip前的大抱佛脚----数论 Noip前的大抱佛脚----图论 Noip前的大抱佛脚----动态规划 Noip前的大抱佛 ...

  2. Noip前的大抱佛脚----Noip真题复习

    Noip前的大抱佛脚----Noip真题复习 Tags: Noip前的大抱佛脚 Noip2010 题目不难,但是三个半小时的话要写四道题还是需要码力,不过按照现在的实力应该不出意外可以AK的. 机器翻 ...

  3. Noip前的大抱佛脚----一些思路

    目录 一些思路 序列 函数问题 网格图 删除和询问 乘法问题 顺序问题 最值问题 研究成果 数论分块套数论分块的复杂度 一些思路 Tags:Noip前的大抱佛脚 序列 线段树(当然还要有主席树啊!) ...

  4. Noip前的大抱佛脚----数论

    目录 数论 知识点 Exgcd 逆元 gcd 欧拉函数\(\varphi(x)\) CRT&EXCRT BSGS&EXBSGS FFT/NTT/MTT/FWT 组合公式 斯特林数 卡塔 ...

  5. Noip前的大抱佛脚----图论

    目录 图论 知识点 二分图相关 DFS找环 并查集维护二分图 二分图匹配的不可行边 最小生成树相关 最短路树 最短路相关 负环 多源最短路 差分约束系统 01最短路 k短路 网络流 zkw费用流 做题 ...

  6. Noip前的大抱佛脚----数据结构

    目录 数据结构 知识点及其应用 线段树 神奇标记 标记不下放 并查集 维护二分图 维护后继位置 堆 可并堆的可持久化 dsu on tree 方式&原理 适用范围 单调队列 尺取合法区间 模板 ...

  7. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  8. Noip前的大抱佛脚----根号对数算法

    根号算法 分块 数列分块入门九题(hzwer) 入门题1,2,3,4,5,7 问题:给一段区间打上标记后单点查询 解法:主要是每块维护一些标记,计算答案等,此类分块较为简单 注意:块大小一般为\(\s ...

  9. Noip前的大抱佛脚----奇技淫巧

    STL函数 set set查找前驱后继 multiset<int>::iterator iter; S.insert(x); iter=S.find(x);//返回迭代器 iter--;/ ...

随机推荐

  1. HAproxy simple

    下载地址 start install: wget     http://www.haproxy.org/download/1.7/src/haproxy-1.7.5.tar.gz tar   -xf  ...

  2. apache软件no_ssl和openssl两种类型的区别

    apache软件同一版本有两种类型:no_ssl和openssl: openssl多了个ssl安全认证模式,它的协议是HTTPS而不是HTTP,这就是带有SSL的服务器与一般网页服务器的区别了. 一般 ...

  3. EBS请求定义成菜单

    1. 将请求定义为“功能”路径:系统管理员 –应用产品-函数输入自定义的功能名称,用户功能名以及说明   “特性”TAB页: 类型选择“表单”,其余两个字段默认:在表单TAB页: 表单字段:选择“运行 ...

  4. Linux内存管理(text、rodata、data、bss、stack&heap)

    一.各内存区段的介绍 系统内的程序分为程序段和数据段,具体又可细分为一下几个部分: (1)text段-代码段 text段存放程序代码,运行前就已经确定(编译时确定),通常为只读,可以直接在ROM或Fl ...

  5. spring-springmvc-hibernate项目小结

    1. web.xml中别忘记加入spring监听器 <listener> <listener-class>org.springframework.web.context.Con ...

  6. thinkphp导出csv文件,用表格输出excel

    1.thinkphp导出csv文件 导出csv文件可能就那几行代码,今天有个问题困扰我好久,就是导出之后出现一些html代码,这个不应该,view里面是空的,controller中最后也没有$this ...

  7. 解决Struts2 json-plugin Date或Timestamp等日期格式带T的问题

    如果没有对日期时间对象类进行json日期格式声明,会出现类似"2013-06-18T12:08:56.23"日期,在日期中间多出一个T字母: 从通过查询数据,以及调试程序发现直到返 ...

  8. Echarts 多曲线“断点”问题解决方法

    Echarts 用来做可视化曲线是非常优秀的一个库.建议使用 Echarts 作为项目的可视化图标库时,仔细研究 官方实例,根据需求来选择类似的示例,下载实例模板来开发,节省时间,减少出错,提高效率. ...

  9. python第三课——数据类型2

    day03: 1.列表:list 特点:有序的(有索引.定义和显示顺序是一致的).可变的(既可以改变元素内容也可以自动扩容).可重复的. 可以存储任何的数据类型数据 定义个列表如下: lt = ['宋 ...

  10. Java & Groovy & Scala & Kotlin - 20.Switch 与模式匹配

    Overview 本章主要介绍高级条件语句中的 switch 语句以及其增强版的模式匹配. Java 篇 Switch 特点 Java 中 switch 语句功能类似 if,但是 switch 主要用 ...