字符串模板整理

挂链式hashhttps://www.luogu.org/problemnew/show/P3823

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N=5e5+7,p=19260817,mod=998244353,gloid=(1<<24)-1;
int n,m,q,a[N],pre[N],nxt[N],cnt[N],f[150];
ull h[150],pw[150];
char s[11000000];
struct Hash{
    struct edge{ull x;int v,nxt;}e[21000000];
    int hd[gloid+1],ecnt;
    void add(ull x,int d)
    {
        int u=x&gloid;
        for(int i=hd[u];i;i=e[i].nxt)if(e[i].x==x){e[i].v+=d;return;}
        e[++ecnt]=(edge){x,d,hd[u]},hd[u]=ecnt;
    }
    int query(ull x)
    {
        int u=x&gloid;
        for(int i=hd[u];i;i=e[i].nxt)if(e[i].x==x)return e[i].v;
        return 0;
    }
}mp;
void merge()
{
    int x,y,L=51,R=50;scanf("%d%d",&x,&y);
    memset(f,0,sizeof f);
    for(int i=x;i&&L>1;i=pre[i])f[--L]=a[i];
    for(int i=y;i&&R<100;i=nxt[i])f[++R]=a[i];
    for(int i=1;i<=R;i++)h[i]=h[i-1]*p+f[i];
    for(int i=L;i<=50;i++)
    for(int j=51;j<=min(R,i+49);j++)
    mp.add(h[j]-h[i-1]*pw[j-i+1],1);
    nxt[x]=y,pre[y]=x;
}
void split()
{
    int x,y,L=51,R=50;scanf("%d",&x),y=nxt[x];
    memset(f,0,sizeof f);
    for(int i=x;i&&L>1;i=pre[i])f[--L]=a[i];
    for(int i=y;i&&R<100;i=nxt[i])f[++R]=a[i];
    for(int i=1;i<=R;i++)h[i]=h[i-1]*p+f[i];
    for(int i=L;i<=50;i++)
    for(int j=51;j<=min(R,i+49);j++)
    mp.add(h[j]-h[i-1]*pw[j-i+1],-1);
    nxt[x]=pre[y]=0;
}
int query()
{
    scanf("%s",s+1);
    int len=strlen(s+1),ret=1,k;
    scanf("%d",&k);
    ull val=0;
    if(k==1)
    {
        for(int i=1;i<=len;i++)ret=1ll*ret*cnt[s[i]]%mod;
        return ret;
    }
    for(int i=1;i<=len;i++)
    {
        val=val*p+s[i];
        if(i>k)val-=pw[k]*s[i-k];
        if(i>=k)ret=1ll*ret*mp.query(val)%mod;
    }
    return ret;
}
int main()
{
    scanf("%d%d",&n,&q);
    pw[0]=1;for(int i=1;i<=50;i++)pw[i]=pw[i-1]*p;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i]+='0',cnt[a[i]]++;
    while(q--)
    {
        int op;scanf("%d",&op);
        if(op==1)merge();
        else if(op==2)split();
        else printf("%d\n",query());
    }
}

最小表示法https://www.luogu.org/problemnew/show/P1368

#include<bits/stdc++.h>
using namespace std;
const int N=6e5+7;
int n,a[N];
int solve()
{
    int i=1,j=2;
    while(i<=n&&j<=n)
    {
        int k=0;
        while(j+k<=2*n&&a[i+k]==a[j+k])k++;
        if(j+k>2*n)break;
        if(a[i+k]>a[j+k])i=max(j,i+k+1),j=i+1;
        else j+=k+1;
    }
    return min(i,j);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i+n]=a[i];
    int pos=solve();
    for(int i=pos;i<pos+n;i++)printf("%d ",a[i]);
}

KMPhttps://www.luogu.org/problemnew/show/P3375

#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e6+7;
int n,m,nxt[N];
char s1[N],s2[N];
void getnxt()
{
    nxt[0]=-1;
    for(int i=1,j=-1;i<=m;i++)
    {
        while(j!=-1&&s2[i]!=s2[j+1])j=nxt[j];
        nxt[i]=++j;
    }
}
void kmp()
{
    for(int i=1,j=0;i<=n;i++)
    {
        while(j&&s1[i]!=s2[j+1])j=nxt[j];
        if(s1[i]==s2[j+1])j++;
        if(j==m)printf("%d\n",i-m+1),j=nxt[j];
    }
}
int main()
{
    scanf("%s%s",s1+1,s2+1);
    n=strlen(s1+1),m=strlen(s2+1);
    getnxt(),kmp();
    for(int i=1;i<=m;i++)printf("%d ",nxt[i]);
}

Trie(异或粽子)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int N=5e5+7;
struct node{int u,id;ll v;};
int n,k,tot=1,ch[N*33][2],sz[N*33];
ll ans,a[N];
bool operator<(node a,node b){return a.v<b.v;}
priority_queue<node>q;
void build(ll x)
{
    int u=1;
    for(int i=31;i>=0;i--)
    {
        int idx;
        if(x&(1ll<<i))idx=1;else idx=0;
        if(!ch[u][idx])ch[u][idx]=++tot;
        u=ch[u][idx];
        sz[u]++;
    }
}
ll query(ll x,int rk)
{
    int u=1;
    ll ret=0;
    for(int i=31;i>=0;i--)
    {
        int idx;
        if(x&(1ll<<i))idx=1;else idx=0;
        if(sz[ch[u][idx^1]]>=rk)ret+=1ll<<i,u=ch[u][idx^1];
        else rk-=sz[ch[u][idx^1]],u=ch[u][idx];
    }
    return ret;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]^=a[i-1];
    for(int i=0;i<=n;i++)build(a[i]);
    for(int i=0;i<=n;i++)q.push((node){i,1,query(a[i],1)});
    for(int tim=1;tim<2*k;tim++)
    {
        node u=q.top();q.pop();
        if(tim&1)ans+=u.v;
        if(u.id==n)continue;
        u.id++,u.v=query(a[u.u],u.id);
        q.push(u);
    }
    printf("%lld",ans);
    return 0;
}

AC自动机https://www.luogu.org/problemnew/show/P5357

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int n,tot,qs,qe,q[N],d[N],ans[N],hd[N],nxt[N],ch[N][26],fail[N];
char str[N*10];
void insert(int id)
{
    int u=0,len=strlen(str+1);
    for(int i=1;i<=len;i++)
    {
        if(!ch[u][str[i]-'a'])ch[u][str[i]-'a']=++tot;
        u=ch[u][str[i]-'a'];
    }
    nxt[id]=hd[u],hd[u]=id;
}
void build()
{
    qs=1,qe=0;
    for(int i=0;i<26;i++)if(ch[0][i])q[++qe]=ch[0][i];
    while(qs<=qe)
    {
        int u=q[qs++];
        for(int i=0;i<26;i++)
        if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q[++qe]=ch[u][i];
        else ch[u][i]=ch[fail[u]][i];
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%s",str+1),insert(i);
    build();
    scanf("%s",str+1);
    int u=0,len=strlen(str+1);
    for(int i=1;i<=len;i++)u=ch[u][str[i]-'a'],d[u]++;
    for(int i=tot;i;i--)
    {
        for(int j=hd[q[i]];j;j=nxt[j])ans[j]=d[q[i]];
        d[fail[q[i]]]+=d[q[i]];
    }
    for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
}

fail树https://www.lydsy.com/JudgeOnline/problem.php?id=3172

#include<cstdio>
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
const int N=1e6+100;
int n,sz,ch[N][26],fail[N],q[N],ans[N],pos[220];
char str[N];
void insert(int k)
{
    int len=strlen(str),u=0;
    for(int i=0;i<len;i++)
    {
        if(!ch[u][str[i]-'a'])ch[u][str[i]-'a']=sz++;
        u=ch[u][str[i]-'a'],ans[u]++;
    }
    pos[k]=u;
}
void build()
{
    int qs=0,qe=0;
    for(int i=0;i<26;i++)if(ch[0][i])fail[ch[0][i]]=0,q[qe++]=ch[0][i];
    while(qs<qe)
    {
        int u=q[qs++];
        for(int i=0;i<26;i++)
        if(ch[u][i])
        {
            int v=fail[u];
            while(v&&!ch[v][i])v=fail[v];
            fail[ch[u][i]]=ch[v][i];
            q[qe++]=ch[u][i];
        }
    }
    while(qe--)ans[fail[q[qe]]]+=ans[q[qe]];
}
int main()
{
    scanf("%d",&n);
    sz=1;
    for(int i=1;i<=n;i++)scanf("%s",str),insert(i);
    build();
    for(int i=1;i<=n;i++)printf("%d\n",ans[pos[i]]);
}

manacherhttps://www.luogu.org/problemnew/show/P3805

#include<bits/stdc++.h>
using namespace std;
const int N=22222222;
char s[N],a[N];
int n,l[N];
void manacher()
{
    int mx=0,po=0;
    for(int i=1;i<n;i++)
    {
        l[i]=mx>i?min(mx-i,l[2*po-i]):1;
        while(s[i-l[i]]==s[i+l[i]])l[i]++;
        if(l[i]+i>mx)mx=l[i]+i,po=i;
    }
}
int main()
{
    scanf("%s",a),n=strlen(a);
    s[0]=s[1]='#';
    for(int i=0;i<n;i++)s[i*2+2]=a[i],s[i*2+3]='#';
    s[n=n*2+2]=0;
    manacher();
    int ans=0;
    for(int i=0;i<n;i++)ans=max(ans,l[i]);
    printf("%d",ans-1);
}

SAhttp://uoj.ac/problem/35

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+99;
char s[N];
int n,m=26,a[N],x[N],y[N],b[N],sa[N],rnk[N],height[N];
bool cmp(int i,int j,int l){return y[i]==y[j]&&(i+l>n?-1:y[i+l])==(j+l>n?-1:y[j+l]);}
void getsa()
{
    memset(b,0,sizeof b);
    int p,j,k;
    for(int i=1;i<=n;i++)b[x[i]=a[i]]++;
    for(int i=1;i<=m;i++)b[i]+=b[i-1];
    for(int i=n;i>=1;i--)sa[b[x[i]]--]=i;
    for(k=1;k<=n;k*=2)
    {
        p=0;
        for(int i=n-k+1;i<=n;i++)y[++p]=i;
        for(int i=1;i<=n;i++)if(sa[i]>k)y[++p]=sa[i]-k;
        memset(b,0,sizeof b);
        for(int i=1;i<=n;i++)b[x[y[i]]]++;
        for(int i=1;i<=m;i++)b[i]+=b[i-1];
        for(int i=n;i>=1;i--)sa[b[x[y[i]]]--]=y[i];
        swap(x,y);
        p=1;x[sa[1]]=1;
        for(int i=2;i<=n;i++)x[sa[i]]=cmp(sa[i-1],sa[i],k)?p:++p;
        if(p==n)break;
        m=p;
    }
    p=k=0;
    for(int i=1;i<=n;i++)rnk[sa[i]]=i;
    for(int i=1;i<=n;height[rnk[i++]]=k)
    {
        if(k)k--;
        j=sa[rnk[i]-1];
        while(s[i+k]==s[j+k])k++;
    }
}
int main()
{
    scanf("%s",s+1);n=strlen(s+1);
    for(int i=1;i<=n;i++)a[i]=s[i]-'a'+1;
    getsa();
    for(int i=1;i<=n;i++)printf("%d ",sa[i]);printf("\n");
    for(int i=2;i<=n;i++)printf("%d ",height[i]);
}

SAMhttps://www.luogu.org/problemnew/show/P3804

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+7;
int n,lst=1,cnt=1,len[N],ch[N][26],fa[N],sz[N],a[N],b[N];
ll ans;
char str[N];
void build(int x)
{
    int p=lst,np=++cnt;
    len[np]=len[p]+1;
    while(p&&!ch[p][x])ch[p][x]=np,p=fa[p];
    if(!p)fa[np]=1;
    else{
        int q=ch[p][x];
        if(len[p]+1==len[q])fa[np]=q;
        else{
            int nq=++cnt;
            memcpy(ch[nq],ch[q],sizeof ch[q]);
            fa[nq]=fa[q],fa[q]=fa[np]=nq,len[nq]=len[p]+1;
            while(p&&ch[p][x]==q)ch[p][x]=nq,p=fa[p];
        }
    }
    sz[lst=np]=1;
}
int main()
{
    scanf("%s",str+1),n=strlen(str+1);
    for(int i=1;i<=n;i++)build(str[i]-'a');
    for(int i=1;i<=cnt;i++)b[len[i]]++;
    for(int i=1;i<=cnt;i++)b[i]+=b[i-1];
    for(int i=1;i<=cnt;i++)a[b[len[i]]--]=i;
    for(int i=cnt;i;i--)
    {
        int now=a[i];
        sz[fa[now]]+=sz[now];
        if(sz[now]>1)ans=max(ans,1ll*sz[now]*len[now]);
    }
    cout<<ans;
}

PAM:CF906E

#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
typedef long long ll;
const int N=1e6+7;
int n,tot,s[N],ch[N][26],len[N],fa[N],tran[N],d[N];
char S[N];
pair<int,int>f[N],g[N];
int extend(int n,int p,char c)
{
    int idx=c-'a';
    while(s[n-len[p]-1]!=c)p=fa[p];
    if(!ch[p][idx])
    {
        int q=++tot,t=fa[p];
        len[q]=len[p]+2;
        while(s[n-len[t]-1]!=c)t=fa[t];
        fa[q]=ch[t][idx],ch[p][idx]=q,d[q]=len[q]-len[fa[q]];
        tran[q]=d[q]==d[fa[q]]?tran[fa[q]]:fa[q];
    }
    return ch[p][idx];
}
int main()
{
    fa[0]=tot=1,len[1]=-1;
    scanf("%s",S+1),n=strlen(S+1);for(int i=1;i<=n;i++)s[(i<<1)-1]=S[i];
    scanf("%s",S+1);for(int i=1;i<=n;i++)s[i<<1]=S[i];
    n=n<<1;
    int st=0;
    for(int i=1;i<=n;i++)
    {
        f[i]=mp(1e9,-1);
        st=extend(i,st,s[i]);
        for(int p=st;p;p=tran[p])
        {
            int lst=i-len[tran[p]]-d[p];
            g[p]=mp(f[lst].first,lst);
            if(d[fa[p]]==d[p])g[p]=min(g[p],g[fa[p]]);
            if(i%2==0)f[i]=min(f[i],mp(g[p].first+1,g[p].second));
        }
        if(i%2==0&&s[i]==s[i-1])f[i]=min(f[i],mp(f[i-2].first,i-2));
    }
    if(f[n].first>n)puts("-1");
    else{
        printf("%d\n",f[n].first);
        int p=n;
        while(p)
        {
            if(p-f[p].second!=2)printf("%d %d\n",f[p].second/2+1,(p+1)/2);
            p=f[p].second;
        }
    }
}

完结撒花

posted @ 2019-06-08 11:15  hfctf0210  阅读(204)  评论(0)    收藏  举报