acm-字符串整理
一、后缀数组
#define maxn 200015
int wa[maxn],wb[maxn],wv[maxn],WS[maxn];
int len, sa[maxn] ;
inline void swap(int &x, int &y) { int t = x ; x = y ; y = t ; }
inline int min(int x, int y) {return x < y ? x : y ; }
inline int max(int x, int y) {return x > y ? x : y ; }
inline int cmp(int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];}
void da(int *r,int *sa,int n,int m){
int i,j,p,*x=wa,*y=wb,*t;
for(i=;i<m;i++) WS[i]=;
for(i=;i<n;i++) WS[x[i]=r[i]]++;
for(i=;i<m;i++) WS[i]+=WS[i-];
for(i=n-;i>=;i--) sa[--WS[x[i]]]=i;
for(j=,p=;p<n;j*=,m=p)
{
for(p=,i=n-j;i<n;i++) y[p++]=i;
for(i=;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=;i<n;i++) wv[i]=x[y[i]];
for(i=;i<m;i++) WS[i]=;
for(i=;i<n;i++) WS[wv[i]]++;
for(i=;i<m;i++) WS[i]+=WS[i-];
for(i=n-;i>=;i--) sa[--WS[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
return;
}
int Rank[maxn], height[maxn];
int s[maxn] ;
void calheight(int *r,int *sa,int n){
int i,j,k=;
for(i=;i<=n;i++) Rank[sa[i]]=i;
for(i=;i<n;height[Rank[i++]]=k)
for(k?k--:,j=sa[Rank[i]-];r[i+k]==r[j+k];k++);
}int lsa[maxn], tmp[maxn] ;
void init_SA(){
int i, t ;
for(len = ; A[len] ; len ++) s[len] = static_cast<int>(A[len]) ;
s[len] = ;
da(s, sa, len+, ) ;
calheight(s, sa, len) ;
} 二、KMP & Manancher
.模板
void getNext() {
int j = , k = - ;
next[] = - ;
while(j < tl ) // next[i] = max {j | t[i, j] == t[i+1 - j, i] } ;
{
if(k == - || t[j] == t[k] ) next[ ++j] = ++ k ;
else k = next[k] ;
}
}
int kmp_Index(){
int l = -, r = sl ;
int i = , j = ;
while(i < sl && j < tl )
{
if(j == - || s[i] == t[j] )
{
if(!j ) l = i ;
else if(j == tl-) r = i ;
i ++ ; j ++ ;
}
else j = next[j] ;
}
printf("%d %d\n", l, r ) ;
if(j == tl ) return i - tl ;
else return - ;
}
int kmp_Count(){
int ans = ;
int i, j ;
if(sl == && tl == )
{
if(s[] == t[] ) return ;
else return ;
}
for(i = , j = ; i < sl ; i ++ )
{
while(j > && s[i] != t[j] ) j = next[j] ;
if(s[i] == t[j] ) j ++ ;
if(j == tl )
{
ans ++ ;
j = next[j] ; // 提前更新,防治t数组越界 ;
}
}
return ans ;
}
.字符串周期
int solve(){
for(i = ; i <= n ; i ++ ){
len = i - next[i] ;
if(next[i] && !(i % len ) ) printf("%d %d\n", i , i / len ) ; //
}
}
.T与S[i,n]的最长公共前缀
//extend[i] 数组表示T 与 S[i , n -1] 的最长公共前缀 ;
void build_Next(){
int k, q, p, a ;
next[] = n ;
for (k = , q = - ; k < n ; k ++, q --)
{
if (q < || k + next[k - a] >= p)
{
if (q < ) q = , p = k ;
//q是B串继续向后匹配的指针,p是A串继续向后匹配的指针,
也是曾经到达过的最远位置+
//q在每次计算后会减小1,直观的讲就是B串向后错了一位
while (p < n && t[p] == t[q]) p ++, q ++ ;
next[k] = q, a = k ;
}
else next[k] = next[k - a] ;
}
}
void extend_KMP(){
int k, q, p, a;
for (k = , q = -; k < n ; k ++, q --)
{
if (q < || k + next[k - a] >= p)
{
if (q < ) q = , p = k ;
while (p < n && q < n && s[p] == t[q])
{
p ++ ;
q ++ ;
}
extend[k] = q ;
a = k ;
}
else extend[k] = next[k - a];
}
}
/*void ExtendKmp(char ss[],int ls,char tt[],int lt){// 直接调用;
int i,j,k;
int Len,L;
j=0;
while(tt[j+1]==tt[j]&&j+1<lt) j++;
next[1]=j,k=1;
for(i=2;i<lt;i++){
Len=k+next[k],L=next[i-k];
if(Len>L+i) next[i]=L;
else{
j=Len-i>0?Len-i:0;
while(tt[i+j]==tt[j]&&i+j<lt) j++;
next[i]=j,k=i;
}
}
j=0;
while(ss[j]==tt[j]&&j<lt&&j<ls) j++;
extend[0]=j,k=0;
for(i=1;i<ls;i++){
Len=k+extend[k],L=next[i-k];
if(Len>L+i) extend[i]=L;
else{
j=Len-i>0?Len-i:0;
while(ss[i+j]==tt[j]&&i+j<ls&&j<lt) j++;
extend[i]=j,k=i;
}
}
} */
.Manancger算法
void initStr(){ // 将原字符串a 转化为加了'#'号的字符串 s,
// 将问题全转化为“长度都为奇数”的情况;
int i , n = strlen(a) ;
for(i = ; i <= n ; i ++ )
{
s[*i] = a[i-] ;
s[*i + ] = '#' ;
}
s[*i] = '\0' ;
}
void manacherMaxPali(){
int i , mx = , r = , id = , ri ; // mx 表示s[i]前面所有回文字串的最右端 ,
for(i = ; i < len ; i ++ )// id 表示取得mx时对应 s 中的位置 ;
{// p[i] = min{ p[id - (i-id) ] , mx - i },求出最小的可能值;
if(mx > i ) p[i] = getMin(p[*id - i ] , mx - i ) ;
else p[i] = ;
// 检测p[i]能否继续增加 ;
for(; s[i - p[i] ] == s[i + p[i] ] ; p[i] ++ ) ;
if(i + p[i] > mx ) //更新 mx 及 id ;
{
mx = i + p[i] ;
id = i ;
}
if(r < p[i] )
{
r = p[i] ;
ri = i ;
}
}
int b = ri - r + ;
for(i = b ; i < ri + r ; i ++ ) if(s[i] != '#' ) printf("%c", s[i]) ;printf("\n") ;
}
三、AC Automation
struct Node{
int c ;
Node * f, *next[] ;
Node(){
memset(next, NULL, sizeof(next)) ;
c = ; f = NULL ;
}
} *que[QMAXN] ;
char kw[], str[MAXN] ;
void insert(Node *rt, char s[]){
int index, i = ;
Node *p = rt ;
while(s[i]){
index = s[i]-'a' ;
if(p->next[index] == NULL) p->next[index] = new Node() ;
p = p->next[index] ;
i ++ ;
}
(p->c) ++ ;
}
void getFail(Node * rt){
Node *tmp, *p ;
int rear = , front = ;
rt->f = NULL ;
que[rear++] = rt ;
while(rear != front){
tmp = que[front++] ; //取出已经更新的节点,更新它的所有孩子节点;
for(int i = ; i < ; i ++)
{
if(tmp->next[i] == NULL) continue ;
if(tmp == rt) tmp->next[i]->f = rt ;
//假设第一层的所有节点fail指针指向根节点;
else //如果不是第一层的,则从父节点的失败指针开始找到一个节点p:
该节点具有有含有i字符的子节点p->next[i];
{ //因为当前指针与p匹配,则其孩子节点就应该p->next[i]匹配;
for(p = tmp->f ; p && (p->next[i] == NULL) ; p = p->f) ;
tmp->next[i]->f = (p == NULL) ? rt : p->next[i] ;
}
que[rear++] = tmp->next[i] ; //将已更新的子节点入队列;
}
}
}
int query(Node * rt){
int i = , count = , index ;
Node *tmp, *p = rt ;
while(str[i])
{
index = str[i] - 'a' ;//如果当前节点不能匹配,且又不是root,则找失败指针;root失败指针为NULL;
while(p->next[index] == NULL && p != rt) p = p->f ;
p = p->next[index] ; //继续匹配;
if(p == NULL) p = rt ; //说明上一轮匹配结束,重新开始匹配;
tmp = p ;
while(tmp != rt && tmp->c != -)
{
count += tmp->c ;
tmp->c = - ; //说明已经遍历过了;
tmp= tmp->f ; //这时,如果tmp失败节点如果是单词结尾的话也要考虑;
}
i++ ;
}
return count ;
}
int solve(){
Node * root ;
while(T --)
{
root = new Node() ;
scanf("%d", &n) ;
for(i = ; i <= n ; i ++){scanf("%s", kw) ;insert(root, kw) ;}
getFail(root) ;scanf("%s", str) ;
printf("%d\n", query(root)) ;
}
四、后缀自动机
/*****************后缀自动机模板**************************************/
const int Smaxn = ; const int maxn = ;
struct node{
node *par,*go[Smaxn];
int num, val ;
}*root,*tail,que[maxn],*top[maxn];
int tot, len ;
void add(int c,int l){
node *p=tail,*np=&que[tot++];
np->val=l;
while(p&&p->go[c]==NULL)
p->go[c]=np,p=p->par;
if(p==NULL) np->par=root;
else
{
node *q=p->go[c];
if(p->val+==q->val) np->par=q;
else
{
node *nq=&que[tot++];
*nq=*q;
nq->val=p->val+ ;
np->par=q->par=nq;
while(p&&p->go[c]==q) p->go[c]=nq,p=p->par;
}
}
tail=np;
}
void init(){
memset(que,,sizeof(que));
tot= ;
len = ;
root = tail= &que[tot++] ;
}
acm-字符串整理的更多相关文章
- 【好好补题,因为没准题目还会再出第三遍!!】ACM字符串-组合数学(官方题解是数位DP来写)
ACM字符串 .长度不能超过n .字符串中仅包含大写字母 .生成的字符串必须包含字符串“ACM”,ACM字符串要求连在一块! ok,是不是很简单?现在告诉你n的值,你来告诉我这样的字符串有多少个 输入 ...
- ACM 字符串 题目整理
AC自动机 UVa 11468 Substring AC自动机+概率DP. 注意要补全不存在的边. 为什么要补全不存在的边呢?补全以后可以直接找到状态的转移,即从所有子节点就可以实现所有状态转移. ...
- ACM字符串输入问题
坑死了..竟然被这个问题困扰了大半个学期,今天搜来翻去终于弄明白了一些,以后固定用这几种用法好了不然总出错QAQ实际测试例子就没放了,死记这里就够用了T-T 概念: gets()函数:用来从标准输入设 ...
- ACM算法整理(不断补充ing)
动态规划 1.背包问题 (1)01背包 ,n) DFR(v,V,C[i]) F[v]=max(F[v],F[v-C[i]]+W[i]); } //初始化时 //若背包不一定装满F全初始化为0 //若装 ...
- ACM +-字符串
+-字符串 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 Shiva得到了两个只有加号和减号的字符串,字串长度相同.Shiva一次可以把一个加号和它相邻的减号交换. ...
- ACM 字符串替换
字符串替换 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 编写一个程序实现将字符串中的所有"you"替换成"we" 输入 ...
- ACM字符串处理算法经典:字符串搜索
语法:result=strfind(char str[],char key[]); 参数: str[]:在这个源字符串查找操作 key[]:搜索字符串.不能为空字符串 回报值: 假设查找成功. ...
- CCF-CSP 第三题字符串整理(模拟大法好)
URL映射 规则的相邻两项之间用‘/’分开,所以我们先把所有项分开,然后依次把两个字符串的对应项匹配即可. 分离字符串这里用字符串流(stringstream)处理,先把所有的‘/’变为空格,然后一个 ...
- acm数据结构整理
一.区间划分 //区间划分+持久化并查集:区间连通情况统计. inline bool comp(Ask x, Ask y){return x.km == y.km ? x.l > y.l : x ...
- SQL Server数据库连接字符串整理
1.sql验证方式的 Data Source=数据源;Initial Catalog= 数据库名;UserId=sql登录账号;Password=密码; Eg: Data Source=.;Initi ...
随机推荐
- [js综合问题汇总]js窗口关闭事件,表单名称,父窗口子窗口,var变量名
<script type="text/javascript"> window.onbeforeunload = onbeforeunload_handler; //wi ...
- Jmeter 使用实践 - 接口 diff 测试
大多数人都使用 Jmeter 做过性能测试,但是在使用的过程中你会发现,它不仅可以做性能测试和功能测试,还能够满足基本的接口测试需求. 相比其他工具,Jmeter 入门门槛较低,安装也比较方便,根据自 ...
- hdu 2897 邂逅明下 博弈论
这个分区间: 1<=n%(p+q)<=p 必败 其他必胜! 代码如下: #include<iostream> #include<stdio.h> #include& ...
- IDEA 运行maven命令时报错: -Dmaven.multiModuleProjectDirectory system propery is not set
在file-setting里面,找到maven的设置: 先加入一个环境变量 然后配置一个JVM的参数: -Dmaven.multiModuleProjectDirectory=$M2_HOME OK ...
- 深入剖析Classloader(二)--根类加载器,扩展类加载器与系统类加载器
原文地址:http://yhjhappy234.blog.163.com/blog/static/31632832201152555245584/?suggestedreading&wumii ...
- mpi冒泡排序并行化
一.实验目的与实验要求 1.实验目的 (1)学会将串行程序改为并行程序. (2)学会mpich2的使用. (3)学会openmp的配置. (4)mpi与openmp之间的比较. 2.实验要求 (1)将 ...
- QGraphicsEffect介绍(十分漂亮)
原文链接:Qt 图形特效(Graphics Effect)介绍 QGraphicsEffect也是Qt-4.6引入的一个新功能.它让给图形元素QGraphicsItem增加更佳视觉效果的编程变得非常简 ...
- R语言学习笔记:生成序列(Genenrating Sequences)
R提供了多种生成不同类型序列的方法.如: > x<-1:20 > x [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 ...
- 使用jenkins自动部署java工程到jboss-eap6.3 -- 1.环境搭建
使用jenkins自动部署java工程到jboss-eap6.3 -- 1.环境搭建 目录 使用jenkins自动部署java工程到jboss-eap6.3 -- 1.环境搭建 使用jenkins自动 ...
- java事务管理(二)
数据库事务和Spring事务是一般面试都会被提到,很多朋友写惯了代码,很少花时间去整理归纳这些东西,结果本来会的东西,居然吞吞吐吐答不上来. 下面是我收集到一些关于Spring事务的问题,希望能帮助大 ...