• BZOJ 3238 【AHOI2013】 差异


    题目链接:差异

      写题时发现这道题当初已经用后缀数组写过了……但是既然学了后缀自动机那就再写一遍吧……

      观察一下题目所给的式子:[sum_{1leqslant i < j leqslant n}len(T_i)+len(T_j)-2lcp(T_i,T_j)]

      可以发现前面两项其实是可以在(O(n))的时间内算出来的。于是我们就只需要考虑后面那一项怎么算。

      题目要求的是所有后缀的最长公共前缀之和,那么把串反一下就变成了所有前缀的最长公共后缀之和。

      那么,我们构出翻转后的串的(parent)树(其实就是原串的后缀树),两个串的公共后缀就是他们在(parent)树上的(lca)节点包含的最长子串长度。

      然后我们就可以枚举每个节点作为(lca),然后统计一下它的两两子树(right)集合大小之积即可。

      下面贴代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define maxn 1000010
    
    using namespace std;
    typedef long long llg;
    
    char s[maxn>>1];
    int n,tot,la,head[maxn],next[maxn],to[maxn],tt;
    int son[maxn][26],len[maxn],fa[maxn],siz[maxn];
    llg ans;
    
    void link(int x,int y){to[++tt]=y;next[tt]=head[x];head[x]=tt;}
    void insert(int p,int x){
    	int np=++tot; siz[np]=1; len[np]=len[p]+1;
    	for(;p && !son[p][x];p=fa[p]) son[p][x]=np;
    	if(!p) fa[np]=1;
    	else{
    		int q=son[p][x];
    		if(len[q]==len[p]+1) fa[np]=q;
    		else{
    			int nq=++tot;
    			memcpy(son[nq],son[q],sizeof(son[q]));
    			fa[nq]=fa[q]; fa[np]=fa[q]=nq; len[nq]=len[p]+1;
    			for(;son[p][x]==q;p=fa[p]) son[p][x]=nq;
    		}
    	}
    	la=np;
    }
    
    void dfs(int u){
    	for(int i=head[u],v;v=to[i],i;i=next[i]){
    		dfs(v);
    		ans-=(llg)siz[u]*siz[v]*len[u],siz[u]+=siz[v];
    	}
    }
    
    int main(){
    	File("a");
    	scanf("%s",s+1); n=strlen(s+1); tot=la=1;
    	for(int i=n>>1;i;i--) swap(s[i],s[n-i+1]);
    	for(int i=1;i<=n;i++) insert(la,s[i]-'a');
    	for(int i=2;i<=tot;i++) link(fa[i],i);
    	dfs(1); ans<<=1; ans+=((llg)(n+1)*n*(n-1))>>1;
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    第一章 线性模型
    Kaggle比赛:从何着手?
    Kaggle初学者五步入门指南,七大诀窍助你享受竞赛
    3.深度学习的实用层面
    软件工程面试题
    PyQT5速成教程-4 Qt Designer实战[上]
    PyQT5速成教程-3 布局管理
    PyQT5速成教程-1 简介与环境搭建
    Anaconda 使用指南
    webpack的loader的原理和实现
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/6297196.html
Copyright © 2020-2023  润新知