一、后缀数组
#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-字符串整理的更多相关文章

  1. 【好好补题,因为没准题目还会再出第三遍!!】ACM字符串-组合数学(官方题解是数位DP来写)

    ACM字符串 .长度不能超过n .字符串中仅包含大写字母 .生成的字符串必须包含字符串“ACM”,ACM字符串要求连在一块! ok,是不是很简单?现在告诉你n的值,你来告诉我这样的字符串有多少个 输入 ...

  2. ACM 字符串 题目整理

    AC自动机 UVa 11468  Substring AC自动机+概率DP. 注意要补全不存在的边. 为什么要补全不存在的边呢?补全以后可以直接找到状态的转移,即从所有子节点就可以实现所有状态转移. ...

  3. ACM字符串输入问题

    坑死了..竟然被这个问题困扰了大半个学期,今天搜来翻去终于弄明白了一些,以后固定用这几种用法好了不然总出错QAQ实际测试例子就没放了,死记这里就够用了T-T 概念: gets()函数:用来从标准输入设 ...

  4. ACM算法整理(不断补充ing)

    动态规划 1.背包问题 (1)01背包 ,n) DFR(v,V,C[i]) F[v]=max(F[v],F[v-C[i]]+W[i]); } //初始化时 //若背包不一定装满F全初始化为0 //若装 ...

  5. ACM +-字符串

    +-字符串 时间限制:1000 ms  |  内存限制:65535 KB 难度:1   描述 Shiva得到了两个只有加号和减号的字符串,字串长度相同.Shiva一次可以把一个加号和它相邻的减号交换. ...

  6. ACM 字符串替换

    字符串替换 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 编写一个程序实现将字符串中的所有"you"替换成"we"   输入 ...

  7. ACM字符串处理算法经典:字符串搜索

    语法:result=strfind(char str[],char key[]); 参数: str[]:在这个源字符串查找操作 key[]:搜索字符串.不能为空字符串 回报值:     假设查找成功. ...

  8. CCF-CSP 第三题字符串整理(模拟大法好)

    URL映射 规则的相邻两项之间用‘/’分开,所以我们先把所有项分开,然后依次把两个字符串的对应项匹配即可. 分离字符串这里用字符串流(stringstream)处理,先把所有的‘/’变为空格,然后一个 ...

  9. acm数据结构整理

    一.区间划分 //区间划分+持久化并查集:区间连通情况统计. inline bool comp(Ask x, Ask y){return x.km == y.km ? x.l > y.l : x ...

  10. SQL Server数据库连接字符串整理

    1.sql验证方式的 Data Source=数据源;Initial Catalog= 数据库名;UserId=sql登录账号;Password=密码; Eg: Data Source=.;Initi ...

随机推荐

  1. ***用php的strpos() 函数判断字符串中是否包含某字符串的方法

    判断某字符串中是否包含某字符串的方法 if(strpos('www.idc-gz.com','idc-gz') !== false){ echo '包含'; }else{ echo '不包含'; } ...

  2. [itint5]两数积全为1

    http://www.itint5.com/oj/#18 这一题,首先如果直接去算的话,很容易就超出int或者long的表示范围了.那么要利用%的性质,(num * 10 + 1) % a = 10 ...

  3. jquery的ajax和原始的ajax这两种方式的使用方法

    jquery的ajax是对原始的ajax进行的封装,方便用户的使用.下面用代码分别举例各自的使用方式. jquery的ajax发送和接收xml数据格式. $.ajax({ type: "PU ...

  4. SQLite入门与分析(四)---Page Cache之事务处理(1)

    写在前面:从本章开始,将对SQLite的每个模块进行讨论.讨论的顺序按照我阅读SQLite的顺序来进行,由于项目的需要,以及时间关系,不能给出一个完整的计划,但是我会先讨论我认为比较重要的内容.本节讨 ...

  5. HeadFirst设计模式之迭代器模式

    一. 1.迭代器模式是对遍历集合元素的抽象 2.The Iterator Pattern provides a way to access the elements of an aggregate o ...

  6. C++中的指针与const

    刚开始接触C++时,指针和const之间的关系有点混乱,现在总结如下: 一.指向const变量的指针 #include<iostream.h> void main() { const in ...

  7. 转XMLHelper

    http://www.cnblogs.com/lixyvip/archive/2009/09/16/1567929.html using System; using System.Collection ...

  8. java ServerSocket服务端编程

    public class Test { public static void main(String[] args) throws Exception{ //1. 构造ServerSocket实例,指 ...

  9. Git教程(1)官网及官方中文教程

    1,Git官网 http://www.git-scm.com/ 2,官方中文教程 http://git-scm.com/book/zh/v2

  10. E-BOM和M-BOM的区别

    简单一点,ENG BOM一般用于试产,正式BOM一般用于量产:ENG BOM是FOR RD设计用的.即TEMP档.并非正式区的.一般的电子零件类的企业都会用到ENG BOM.在EBS中,ENG BOM ...