zoukankan      html  css  js  c++  java
  • BZOJ3238 [Ahoi2013]差异

    传送门

    裸的SA?

    SA求出来然后单调栈+height搞一搞就好了啊qwq

    话说,为什么我这玩意自闭了啊

    吸氧就能过 不吸就挂QAQ

    好像是longlong强转出问题了emm

    不管了我自闭了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define inf 20021225
    #define ll long long
    #define mxn 500010
    using namespace std;
    
    int sa[mxn],ht[mxn],rk[mxn],tp[mxn],pre[mxn],n,m;
    char ch[mxn];
    void sort()
    {
        for(int i=1;i<=m;i++)	pre[i]=0;
        for(int i=1;i<=n;i++)	pre[rk[i]]++;
        for(int i=1;i<=m;i++)	pre[i]+=pre[i-1];
        for(int i=n;i;i--)	sa[pre[rk[tp[i]]]--]=tp[i];
    }
    int id(char c){return c-'a'+1;}
    void getSA()
    {
        m=26;
        for(int i=1;i<=n;i++)	pre[rk[i]=id(ch[i])]++;
        for(int i=1;i<=m;i++)	pre[i]+=pre[i-1];
        for(int i=n;i;i--)	sa[pre[rk[i]]--]=i;
        for(int k=1,num;num<n;k<<=1)
        {
            num=0;
            for(int i=n-k+1;i<=n;i++)	tp[++num]=i;
            for(int i=1;i<=n;i++)	if(sa[i]>k)	tp[++num]=sa[i]-k; 
            sort();
            memcpy(tp,rk,sizeof(rk));
            rk[sa[1]]=num=1;
            for(int i=2;i<=n;i++)
                rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+k]==tp[sa[i-1]+k])?num:++num;
            m=num;
        }
    }
    void getheight()
    {
        int k=0;
        for(int i=1;i<=n;i++)	rk[sa[i]]=i;
        for(int i=1;i<=n;i++)
        {
            if(k)	k--;
            int j=sa[rk[i]-1];
            while(i+k<=n&&j+k<=n&&ch[j+k]==ch[i+k])	k++;
            ht[rk[i]]=k;
        }
    }
    int stk[mxn],tt,l[mxn],r[mxn];ll ans;
    int main()
    {
        //freopen("10.in","r",stdin);
        scanf("%s",ch+1);
        n=strlen(ch+1);getSA();getheight();
        for(int i=1;i<=n;i++)	ans+=(ll)i*(n-1);
        ht[1]=ht[n+1]=-1;stk[tt=1]=1;
        for(int i=2;i<=n+1;i++)
        {
            while(tt&&ht[i]<ht[stk[tt]])
                r[stk[tt]]=i-1,tt--;
            l[i]=stk[tt]+1;stk[++tt]=i;
        }
        for(int i=2;i<=n;i++)	ans-=2ll*ht[i]*(i-l[i]+1)*(r[i]-i+1);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    SqlMapClient对象
    斐波拉契数列的由来
    马士兵struts2
    [转]ASP.NET Repeater控件
    C# 使用委托
    C# 实现图片的放大缩小和平移
    托管改变属性的值InvokeRequired
    [转]正确使用 RamDisk Plus 的方法解决分配内存后占用系统内存的问题
    简单学习Infopath
    C# Image与ByteArray转换
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/10321926.html
Copyright © 2011-2022 走看看