zoukankan      html  css  js  c++  java
  • AHOI2013 差异

    题目链接:戳我

    题目中让我们求后缀的前缀,我们可以把串反过来,然后求前缀的后缀......这样就可以用SAM做了。

    构建出来SAM,那么在后缀树上,两个串的前缀的后缀就是后缀树上这两个前缀节点的LCA的len。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 1000010
    using namespace std;
    int last=1,tot=1,len;
    int siz[MAXN],a[MAXN],c[MAXN];
    char s[MAXN];
    long long ans;
    struct Node{int ch[26],ff,len;}t[MAXN<<1];
    inline void extend(int c)
    {
        int p=last,np=++tot;last=np;
        t[np].len=t[p].len+1;
        while(p&&!t[p].ch[c]) t[p].ch[c]=np,p=t[p].ff;
        if(!p) t[np].ff=1;
        else
        {
            int q=t[p].ch[c];
            if(t[q].len==t[p].len+1) t[np].ff=q;
            else
            {
                int nq=++tot;
                t[nq]=t[q];t[nq].len=t[p].len+1;
                t[np].ff=t[q].ff=nq;
                while(p&&t[p].ch[c]==q) t[p].ch[c]=nq,p=t[p].ff;
            }
        }
        siz[np]=1;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%s",s+1);
        len=strlen(s+1);
        for(int i=len;i>=1;i--) extend(s[i]-'a');
        for(int i=1;i<=tot;i++) c[t[i].len]++;
        for(int i=1;i<=tot;i++) c[i]+=c[i-1];
        for(int i=1;i<=tot;i++) a[c[t[i].len]--]=i;
        for(int i=tot;i;i--) siz[t[a[i]].ff]+=siz[a[i]];
        for(int i=1;i<=len;i++) ans+=1ll*i*(len-1);
        for(int i=2;i<=tot;i++) ans-=1ll*(siz[i]-1)*siz[i]*(t[i].len-t[t[i].ff].len);
        printf("%lld
    ",ans);
        return 0;
    }
    
    
    
  • 相关阅读:
    数据量过大时数据库操作的处理
    VC中回调函数的用法
    基于BindingSource的WinForm开发
    VC获取各类指针
    GetSystemMetrics()函数的用法
    samba建立个人专享网盘
    Windows 7下用Windows照片查看器打开图片速度变慢的解决方案
    这是一个模板
    QT中编译和使用OPENCV
    MFC日志(2011.4.9)
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10761505.html
Copyright © 2011-2022 走看看