• BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)


    题目链接

    (Description)

    (Solution)

    len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次。

    [sum_{i=1}^nsum_{j=i+1}^n i+j = (n-1)*sum_{i=1}^n = (n-1)*frac{n*(n+1)}{2} ]

    对于后半部分:

    SAM:求后缀的LCP,我们可以想到将字符串反转,求前缀的最长公共后缀。
    parent树上每个叶子节点都对应一个前缀,两个节点间的最长公共后缀在它们的LCA处,长度为len[LCA]。
    于是对于每个节点我们统计有多少对叶子节点的LCA为它。树形DP就可以了。
    非后缀节点的size是等于0,但是最后一样DP。

    SA:LCP当然是看height了。枚举后缀,计算它与之前串所构成的LCP。
    如果ht[i]>=ht[i-1],那么它与之前串的LCP和i-1一样;否则ht[i]就是这部分的LCP长度。
    用单调栈维护离i最近且ht[p]<=i的位置p,则f[i]=f[p]+(i-p)*ht[i]。

    //122404kb	1924ms
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    const int N=1e6+5;
    
    struct Suffix_Automaton
    {
    	int n,las,tot,fa[N],son[N][26],len[N],sz[N],A[N],tm[N];
    	char s[N>>1];
    	void Insert(int c)
    	{
    		int p=las,np=++tot;
    		len[las=np]=len[p]+1, sz[np]=1;
    		for(; p&&!son[p][c]; p=fa[p]) son[p][c]=np;
    		if(!p) fa[np]=1;
    		else
    		{
    			int q=son[p][c];
    			if(len[q]==len[p]+1) fa[np]=q;
    			else
    			{
    				int nq=++tot; len[nq]=len[p]+1;
    				memcpy(son[nq],son[q],sizeof son[q]);
    				fa[nq]=fa[q], fa[q]=fa[np]=nq;
    				for(; son[p][c]==q; p=fa[p]) son[p][c]=nq;
    			}
    		}
    	}
    	void Build()
    	{
    		las=tot=1;
    		scanf("%s",s+1), n=strlen(s+1);
    		std::reverse(s+1,s+1+n);
    		for(int i=1; i<=n; ++i) Insert(s[i]-'a');
    		for(int i=1; i<=tot; ++i) ++tm[len[i]];
    		for(int i=1; i<=n; ++i) tm[i]+=tm[i-1];
    		for(int i=1; i<=tot; ++i) A[tm[len[i]]--]=i;
    
    		long long res=0;
    		for(int i=tot,x=A[i],f; i; x=A[--i])
    			f=fa[x], res+=1ll*sz[f]*sz[x]*len[f], sz[f]+=sz[x];
    		printf("%lld
    ",1ll*n*(n+1)/2*(n-1)-(res<<1));
    	}
    }sam;
    
    int main()
    {
    	sam.Build();
    	return 0;
    }
    
  • 相关阅读:
    远程服务器上的weblogic项目管理(二)发布完成后如何重启weblogic容器
    Oracle中日期和时间类函数
    程序员应如何提高实效?读《程序员修炼之道》有感
    远程服务器上的weblogic项目管理(一)项目部署与更新流程
    远程服务器上的weblogic项目管理(四)filelock not found错误解决方法
    浅拷贝与深拷贝
    for...of 与 for...in
    工厂函数创建对象
    Promise
    闭包内存泄漏解决方法
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9249744.html
Copyright © 2020-2023  润新知