字符串题模板集合

后缀数组

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <limits>
#include <set>
#include <map>
using namespace std;
#define SZ 666666
int n,sa[SZ],t[SZ],rank[SZ],qzh[SZ],tmpsa[SZ],tmpr[SZ],h[SZ];
char s[SZ];
bool same(int a,int b,int p) {return t[a]==t[b]&&t[a+p]==t[b+p];}
void getsa(int n,int m=233)
{
    for(int i=0;i<n;i++) rank[i]=s[i], ++qzh[rank[i]];
    for(int i=1;i<m;i++) qzh[i]+=qzh[i-1];
    for(int i=n-1;i>=0;i--) sa[--qzh[rank[i]]]=i;
    for(int j=1;j<=n;j<<=1)
    {
        int cur=-1;
        for(int i=n-j;i<n;i++) tmpsa[++cur]=i;
        for(int i=0;i<n;i++) if(sa[i]>=j) tmpsa[++cur]=sa[i]-j;
        for(int i=0;i<n;i++) tmpr[i]=rank[tmpsa[i]];
        for(int i=0;i<m;i++) qzh[i]=0;
        for(int i=0;i<n;i++) ++qzh[tmpr[i]];
        for(int i=1;i<m;i++) qzh[i]+=qzh[i-1];
        for(int i=n-1;i>=0;i--) t[i]=rank[i], sa[--qzh[tmpr[i]]]=tmpsa[i];
        m=0;
        for(int i=0;i<n;i++)
            rank[sa[i]]=(i>0&&same(sa[i],sa[i-1],j))?m:++m;
        ++m;
    }
    for(int i=0;i<n;i++) rank[sa[i]]=i;
}
void geth(int n)
{
    int p=0;
    for(int i=0;i<n;i++)
    {
        if(p) --p;
        int ls=sa[rank[i]-1];
        while(s[ls+p]==s[i+p]) p++;
        h[rank[i]]=p;
    }
}
int main()
{
    scanf("%s",s);
    n=strlen(s); getsa(n+1); geth(n);
    for(int i=1;i<=n;i++) printf("%d ",sa[i]+1);
    putchar(10);
    for(int i=2;i<=n;i++) printf("%d ",h[i]);
}

hash+kmp(搭配风味更佳)

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
using namespace std;
#define SZ 2333333
typedef long long ll;
ll MOD=1000000007,cm[SZ],cmn[SZ];
ll qp(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%MOD;
        a=a*a%MOD; b>>=1;
    }
    return ans;
}
struct HashKMP
{
char s[SZ+1]; int n;
ll hash[SZ+1];
void pre()
{
    n=strlen(s);
    for(int i=n-1;i>=0;i--) hash[i]=(hash[i+1]+cm[n-1-i]*(s[i]-‘a‘+1)%MOD)%MOD;
}
ll ghash(int l,int r)
{
    return ((hash[l]-hash[r+1])*cmn[n-1-r]%MOD+MOD)%MOD;
}
int next[SZ+3];
void gnext()
{
    next[0]=-1;
    int j=-1;
    for(int i=1;s[i];i++)
    {
        while(j!=-1&&s[i]!=s[j+1]) j=next[j];
        if(s[i]==s[j+1]) ++j;
        next[i]=j;
    }
}
void kmp(char* a)
{
    int j=-1;
    for(int i=0;a[i];i++)
    {
        while(j!=-1&&s[j+1]!=a[i]) j=next[j];
        if(s[j+1]==a[i]) ++j;
        //do sth
        printf("%d w %d\n",i,j);
    }
}
}ha;
void getcm()
{
    cm[0]=cmn[0]=1; ll gg=qp(31,MOD-2);
    for(int i=1;i<=1234567;i++) cm[i]=cm[i-1]*31%MOD;
    for(int i=1;i<=1234567;i++) cmn[i]=cmn[i-1]*gg%MOD;
}

char b[SZ+3];
int main()
{
    getcm();
    scanf("%s",ha.s);
    ha.pre();
    scanf("%s",b);
    ha.gnext();
    ha.kmp(b);
}

后缀自动机+序列自动机

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <limits>
#include <set>
#include <map>
using namespace std;
int MOD=998244353;
#define SZ 4008
#define S 26 //字符集
struct AM
{
int rot,ch[SZ][S],C,cnt[SZ];
};
struct SeqAM: public AM
{
int par[SZ],lst[S];
SeqAM()
{
    C=rot=1;
    for(int i=0;i<S;i++) lst[i]=rot;
}
void ins(char c)
{
    ++C; par[C]=lst[c];
    for(int i=0;i<S;i++)
    {
        for(int g=lst[i];g&&!ch[g][c];g=par[g]) ch[g][c]=C;
    }
    lst[c]=C;
}
void getcnt()
{
    for(int i=1;i<=C;i++) cnt[i]=1;
    for(int i=C;i>=1;i--)
    {
        for(int j=0;j<S;j++) cnt[i]+=cnt[ch[i][j]], cnt[i]%=MOD;
    }
}
}SeqA,SeqB;
struct SufAM: public AM
{
int ml[SZ],fail[SZ],lst,cl,qzh[SZ],od[SZ];
SufAM() {C=lst=rot=1; cl=0;}
void ins(char c)
{
    int x=++C,len=++cl,p=lst;
    lst=x; ml[x]=len;
    for(;p&&!ch[p][c];p=fail[p]) ch[p][c]=x;
    if(!p) fail[x]=rot;
    else if(ml[ch[p][c]]==ml[p]+1) fail[x]=ch[p][c];
    else
    {
        int chh=ch[p][c],cm=++C;
        ml[cm]=ml[p]+1; fail[cm]=fail[chh];
        for(int i=0;i<S;i++) ch[cm][i]=ch[chh][i];
        fail[chh]=fail[x]=cm;
        for(;ch[p][c]==chh;p=fail[p]) ch[p][c]=cm;
    }
}
void getcnt()
{
    for(int i=0;i<SZ;i++) qzh[i]=0;
    for(int i=1;i<=C;i++) qzh[ml[i]]++;
    for(int i=1;i<SZ;i++) qzh[i]+=qzh[i-1];
    for(int i=1;i<=C;i++) od[qzh[ml[i]]--]=i;
    for(int i=1;i<=C;i++) cnt[i]=1;
    for(int i=C;i>=1;i--)
    {
        for(int j=0;j<S;j++) cnt[od[i]]+=cnt[ch[od[i]][j]], cnt[od[i]]%=MOD;
    }
}
}SufA,SufB;

AC自动机

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <limits>
#include <set>
#include <map>
using namespace std;
#define SZ 1000099
int rot=1,ch[SZ][29],fail[SZ],cnt[SZ],e=1;
void insert(char* s)
{
    int cur=rot;
    for(int i=0;s[i];i++)
    {
        int c=s[i]-‘a‘;
        if(!ch[cur][c]) ch[cur][c]=++e;
        cur=ch[cur][c];
    }
    cnt[cur]++;
}
int qs[SZ],h=0,t=0;
void bfail()
{
    h=t=0; fail[rot]=rot;
    for(int i=0;i<26;i++)
    {
        if(!ch[rot][i])
        {
            ch[rot][i]=rot; continue;
        }
        fail[ch[rot][i]]=rot;
        qs[t++]=ch[rot][i];
    }
    while(h!=t)
    {
        int cur=qs[h++];
        for(int c=0;c<26;c++)
        {
            if(!ch[cur][c]) ch[cur][c]=ch[fail[cur]][c];
            else
            {
                fail[ch[cur][c]]=ch[fail[cur]][c];
                qs[t++]=ch[cur][c];
            }
        }
    }
}
int match(char* s)
{
    int cur=rot,ans=0;
    for(int i=0;s[i];i++)
    {
        int c=s[i]-‘a‘; cur=ch[cur][c];
        for(int f=cur;f!=rot;f=fail[f]) ans+=cnt[f], cnt[f]=0;
    }
    return ans;
}

int n,T;
char str[SZ];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        rot=e=1;
        memset(ch,0,sizeof(ch));
        memset(fail,0,sizeof(fail));
        memset(cnt,0,sizeof(cnt));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str);
            insert(str);
        }
        bfail();
        scanf("%s",str);
        printf("%d\n",match(str));
    }
}

manacher

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define SZ 666666
int p[SZ];
char str[SZ];
void manacher()
{
    int ml=0,id;
    for(int i=0;str[i];i++)
    {
        if(ml>i) p[i]=min(p[2*id-i],p[id]+id-i);
        else p[i]=1;
        while(i>=p[i]&&str[i+p[i]]==str[i-p[i]]) ++p[i];
        if(p[i]+i>ml) ml=p[i]+i, id=i;
    }
}
char s[SZ];
void init()
{
    str[0]=‘$‘; int n=1;
    for(int i=0;s[i];i++) str[n++]=s[i], str[n++]=‘$‘;
    str[n]=0;
}
int main()
{
    while(gets(s))
    {
        if(!s[0]) continue;
        init(); manacher();
        int ans=0;
        for(int i=0;str[i];i++) ans=max(ans,p[i]);
        printf("%d\n",ans-1);
    }
    return 0;
}

回文树

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <limits>
#include <set>
#include <map>
using namespace std;
struct PTree
{
#define SZ 666666
int ch[SZ][26],len[SZ],fail[SZ],cnt[SZ],s[SZ],cl,an,lst;
int addn(int l) {len[an]=l; return an++;}
PTree()
{
    cl=an=lst=0;
    memset(ch,0,sizeof(ch));
    addn(0); addn(-1);
    fail[0]=1; s[0]=-233;
}
int gfail(int x,int l)
{
    while(s[l-len[x]-1]!=s[l]) x=fail[x];
    return x;
}
void add(int c)
{
    s[++cl]=c;
    int cp=gfail(lst,cl);
    if(!ch[cp][c])
    {
        int nn=addn(len[cp]+2);
        fail[nn]=ch[gfail(fail[cp],cl)][c];
        ch[cp][c]=nn;
    }
    cnt[lst=ch[cp][c]]++;
}
void getcnt()
{
    for(int i=an-1;i>=2;i--) cnt[fail[i]]+=cnt[i];
}
}pt;

char s[SZ];
int main()
{
    scanf("%s",s);
    for(int i=0;s[i];i++) pt.add(s[i]-‘a‘);
    pt.getcnt();
    long long ans=0;
    for(int i=2;i<=pt.an;i++) ans=max(ans,pt.len[i]*(long long)pt.cnt[i]);
    printf("%lld\n",ans);
}

本来这篇文章是想放一些字符串题目,在前面整一下模板...没想到整了这么长...就下一篇文章放题目好了。

时间: 2024-11-16 11:24:12

字符串题模板集合的相关文章

P3709 大爷的字符串题(50分)

题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符x,然后把x从这个区间中删除,你要维护一个集合S 如果S为空,你rp减1 如果S中有一个元素不小于x,则你rp减1,清空S 之后将x插入S 由于你是大爷,平时做过的题考试都会考到,所以每次询问你搞完这段区间的字符之后最多还有多少rp?rp初始为0 询问之间不互相影响~ 输入输出格

【转载】POJ水题大集合

POJ水题大集合 poj1000:A+B problempoj1002:电话上按键对应着数字.现在给n个电话,求排序.相同的归一类poj1003:求最小的n让1+1/2+1/3+...+1/n大于给的一个实数poj1004:求一堆实数的平均数poj1005:由坐标 (0,0) 开始,以半圆为形状每年侵蚀50m^2,问(0,0)开始到(x,y)结束需要多长时间poj1006:三个周期是常数.现在给三个周期出现高峰的时候,问下一次出现高峰是什么时候poj1007:求字符串排序poj1008:一种日历

洛谷 P3709 大爷的字符串题

https://www.luogu.org/problem/show?pid=3709 题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符x,然后把x从这个区间中删除,你要维护一个集合S 如果S为空,你rp减1 如果S中有一个元素不小于x,则你rp减1,清空S 之后将x插入S 由于你是大爷,平时做过的题考试都会考到,所以每次询问

C库函数中字符串处理函数集合(转)

C库函数中字符串处理函数集合(转) C库函数中字符串处理函数集合 bcmp 原型:extern int bcmp(const void *s1, const void *s2, int n); 用法:#include <string.h> 功能:比较字符串s1和s2的前n个字节是否相等 说明:如果s1=s2或n=0则返回零,否则返回非零值.bcmp不检查NULL. bcopy 原型:extern void bcopy(const void *src, void *dest, int n); 用

字符串HASH模板 取自挑战程序设计竞赛(第2版)

/*===================================================* 从b串中寻找和a串长度相同的子串,返回开始位置 不保证绝对正确,发生冲突概率为O(sqrt(n)), n为哈希函数的最大值 \*===================================================*/ #define ull unsigned long long const ull B = 1e8+7; /*according to the book*/

c\c++ 字符串处理大集合[转]

1 rember this 2 3 strncpy(a,b,5); 4 a[5]='\0'; 5 6 char a[10]; 7 memset(a,'#',sizeof(a)); 8 a[10]='\0'; 9 10 刚开始学C/C++时,一直对字符串处理函数一知半解,这里列举C/C++字符串处理函数 11 12 ,希望对初学者有一定的帮助. 13 14 C: 15 16 char st[100]; 17 1. 字符串长度 18 strlen(st); 19 20 2. 字符串比较 21 str

模板集合——持续更新中

首先   sro_Cydiater_orz   sro_姬树流_orz 两位开搞模板集合已久的大神 1.对拍 1 @echo off 2 set path=C:\MinGWStudio\MinGW\bin 3 g++ -o makedata.exe makedata.cpp 4 g++ -o right.exe right.cpp 5 g++ -o test.exe test.cpp 6 set path=C:\Windows\system32 7 :loop 8 makedata.exe 9

luogu P3709 大爷的字符串题

二次联通门 : luogu P3709 大爷的字符串题 /* luogu P3709 大爷的字符串题 莫队 看了半天题目 + 题解 才弄懂了要求什么... 维护两个数组 一个记录数字i出现了几次 一个记录出现了i次的有几个数.. */ #include <algorithm> #include <cstdlib> #include <cstdio> #include <cmath> #define Max 200090 void read (int &

JSon_零基础_008_将JSon格式的&quot;数组&quot;字符串转换为List集合

将JSon格式的"数组"字符串转换为List集合. 应用此技术从一个json对象字符串格式中得到一个java对应的对象. JSONObject是一个“name.values”集合, 通过get(key)方法取得key对应的value部分(字符串). 通过getJSONObject(key)可以取得一个JSONObject对象. 通过getJSONArray(key)可以得到一个JSONArray对象. 导入jar包: 编写:po(bean)类: package com.west.web